Можно ли подключить шрифт при переводе страницы

256
23 марта 2018, 10:49

Ситуация такая: имеется сайт использующий шрифт определенной языковой группы, понятное дело, при переводе страницы средствами хром, мозилла и т.д. едет верстка, поскольку используемый шрифт имеет межбуквенное расстояние гораздо больше, чем кириллица и латиница. Заказчик требует устранить "баг верстки", но сколько бы я ни искал инфы по этому вопросу, прихожу ко мнению, что это не исправить никак, кроме верстки отдельного сайта на кириллице/латинице, использующего корректный шрифт. Или я не прав? Как вариант, заказчик, предложил установить запрет на перевод блока/блоков. Но, опять же, на мой взгляд, это невозможно.

Answer 1

По моему получается так что нужно использовать шрифт с поддержкой кирилицы. Остальное костыли той или иной степени.

Ну как вариант можно следить за изменением содержимого и проверять из какого алфавита символы. И менять шрифты. В примере я использовал SimSun шрифт, так как он тоже плохо переносит кириллицу.

К сожалению тут код не работает, тк большая часть сайта на русском и онлайн переводчик не срабатывает.

function fixedCharCodeAt (str, idx) { 
    var code = str.charCodeAt(idx); 
    if (0xD800 <= code && code <= 0xDBFF) {  
        // Верхний вспомогательный символ 
        var hi = code; 
        var low = str.charCodeAt(idx+1); 
        return ((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000; 
    } 
    if (0xDC00 <= code && code <= 0xDFFF) {  
       // Нижний вспомогательный символ 
        var hi = str.charCodeAt(idx-1); 
        var low = code; 
        return ((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000; 
    } 
    return code; 
} 
document.getElementById("testdiv").addEventListener('DOMSubtreeModified', function () { 
  mydiv=document.getElementById("testdiv"); 
  //самая простая проверка - читаем код первого символа в юникоде 
  //лучше проверять большее число символов так как перевод текста может быть частичным 
  //если <1280 то кирилица или латиница 
  c=fixedCharCodeAt(mydiv.textContent,0); 
  if (c<1280) { 
    //обнаружили кирилицу 
    document.body.style.fontFamily = "Tahoma"; 
  } else { 
    document.body.style.fontFamily = "SimSun"; 
  } 
}, false);
body { 
font-family: 'SimSun'; 
}
<div id="testdiv">サイト翻訳サ</div> 
 
<div style="font-family: 'SimSun';">サイト翻訳サ</div>

Вот код целиком чтобы проверить локально

<html>
<head>
<style>
body {
font-family: 'SimSun';
}
</style>
</head>
<body>
<div id="testdiv">サイト翻訳サ</div>
<div style="font-family: 'SimSun';">サイト翻訳サ</div>
<script type="text/javascript">
//функция чтобы узнать код символа в юникоде
function fixedCharCodeAt (str, idx) {
    var code = str.charCodeAt(idx);
    if (0xD800 <= code && code <= 0xDBFF) { 
        // Верхний вспомогательный символ
        var hi = code;
        var low = str.charCodeAt(idx+1);
        return ((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;
    }
    if (0xDC00 <= code && code <= 0xDFFF) { 
       // Нижний вспомогательный символ
        var hi = str.charCodeAt(idx-1);
        var low = code;
        return ((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;
    }
    return code;
}
document.getElementById("testdiv").addEventListener('DOMSubtreeModified', function () {
  mydiv=document.getElementById("testdiv");
  //самая простая проверка - читаем код первого символа в юникоде
  //лучше проверять большее число символов так как перевод текста может быть частичным
  //если <1280 то кирилица или латиница
  c=fixedCharCodeAt(mydiv.textContent,0);
  if (c<1280) {
    //обнаружили кирилицу
    document.body.style.fontFamily = "Tahoma";
  } else {
    document.body.style.fontFamily = "SimSun";
  }
}, false);        
</script>
</body>
</html>
Answer 2

Можно к примеру, когда отрабатывает скрипт перевода, доставлять класс верстки. В котором поменять размеры шрифтов и межстрочные интервалы. Самый простой способ реализации.

Answer 3

В Chrome при переводе страницы добавляется класс translated-ltr или translated-rtl, а при показе оригинального текста - удаляется.
Собственно осталось отследить изменение атрибута.

var html = document.getElementsByTagName('html')[0],
    callback = function(mutationsList) {
        if(html.className.match('translated')){
            console.log('Страница переведена');
        }else{
            console.log('Оригинальная страница');
        }
    };
var observer = new MutationObserver(callback);
observer.observe(html, {attributes: true});

JavaScript, как таковой, не обязателен. Ибо можно манипулировать через CSS

body {
    font-family: 'KozGoPro';
}
html.translated-ltr body {
    font-family: 'Tahoma';
}

PS:
Для мозилы и т. д. Например добавляем div со словом "Computer" и id="langchange". При событии проверяем регуляркой на кириллицу. Оригинальная страница на английском.

if(typeof MutationObserver == 'function'){
    var html = document.getElementsByTagName('html')[0],
        div = document.getElementById('langchange'),
        config = {
            childList: true,
            characterData: true,
            subtree: true,
            characterDataOldValue: true
        },
        callback = function(mutationsList) {
            var text = mutationsList[0].target.textContent;
            if(/^[А-Яа-я]+/.test(text)){
                console.log('Страница Переведена');
                html.classList.add('translate');
            }else{
                console.log('Оригинальная страница');
                html.classList.remove('translate');
            }
        };
    var observer = new MutationObserver(callback);
    observer.observe(div, config);
}
READ ALSO
iOS странным образом выводит блоки

iOS странным образом выводит блоки

Имеется вот такое поведение: С чем это связано? Почему ios дублирует некоторые блоки, заменяя при этом другие, да еще "пережевывая" подобным...

214
Совет по таблицам MySql

Совет по таблицам MySql

Есть товар у которого 3 размера и соотв3 цены, сейчас всё сделано на JS и при клике на 1 из 3 input[type="radio"] подставляется цена и размер указанные...

242
No module named &#39;pymysql&#39; FLASK в то время, когда он есть

No module named 'pymysql' FLASK в то время, когда он есть

Уже не знаю сколько разбираюсь с этой проблемой

243
Bad Gateway (502.3) из-за TagHelper&#39;а

Bad Gateway (502.3) из-за TagHelper'а

Есть простой метод (экшен) в контроллере:

253