2015-08-14 3 views
6

Я работаю над графическим интерфейсом, который может использовать несколько языков. Оригинальные HTML-файлы, с которыми я работал, были полностью статичными. Поэтому, если перевод был необходим, мне пришлось разбирать все файлы, отмечая, где были какие-то слова или термины, собрать все их в отдел перевода и ввести эти переводы в новые языковые файлы.Использование Javascript для изменения языка сайта

Поскольку эти файлы были полностью статичными, это означало необходимость переводить целые секции несколько раз. Не очень эффектно.

Так что теперь я работаю над каким-то словарем в Javascript, чтобы просто обменять термины на этих сайтах. В основном он работает следующим образом:

var dicEnglish = { 
term 1: "This is the English text" 
Ref: "Another English text" 
} 
var dicFrench = { 
term 1: "This is the French text" 
Ref: "Another French text" 
} 

В котором содержится весь возможный контент, который необходимо изменить. Каждый кандидат в HTML-код получает class="dicRef" id="l_dicTag_#" в качестве идентификатора, который я нарежьте вниз к словарной теге и обмена со следующим кодом:

var imgSrc = "en"; 
var ActiveDic; 
var langSel; 
if(window.name){ 
    langSel=window.name; 
    } 
else{langSel="English"; 
} 

function LangChange(){ 
langClass = document.getElementsByClassName("dicRef"); 
var i = langClass.length; 
var Start, Stop, idSrc, idDic; 
var navText; 

switch(langSel){ 
    case "French": 
     langSel="French"; 
     imgSrc = "en"; 
     navText="Anglais"; 
     break; 
    case "English": 
    case "Anglais": 
    default: 
     langSel="English"; 
     imgSrc = "fr"; 
     navText="French"; 
     break; 
    } 
ActiveDic="dic"+langSel; 
window.name=langSel; 

while(i--){ 
    idSrc = langClass[i].id; 
    Start=idSrc.indexOf("_")+1; 
    Stop=idSrc.lastIndexOf("_"); 
    idDic=idSrc.slice(Start,Stop); 
    if(window[ActiveDic][idDic]){ 
     document.getElementById(idSrc).innerHTML=window[ActiveDic][idDic];} 
    else{ 
     document.getElementById(idSrc).innerHTML="N/A"; 
    } 
} 
if(document.getElementById("imgSel")){ 
    document.getElementById("imgSel").src="../../img/"+imgSrc+".gif"; 
} 
if (document.getElementById("l_SelLang1_1")){ 
    document.getElementById("l_SelLang1_1").innerHTML=navText; 
} 
} 

Проблема заключается в уникальности идентификатора тега. Поскольку некоторые термины могут возникать более одного раза, а некоторые из них генерируются, счетчик необходим. Я предпочел бы опустить счетчик, но не могу найти какой-либо другой идентификатор, чтобы разобраться во всех целевых терминах и изменить их содержимое.

Поскольку я хочу быть в безопасности в будущем, я бы предпочел решение, позволяющее обрабатывать возможный третий язык. Работа с внутренним HTML должна была бы пометить один и тот же термин несколько раз, один раз для каждого языка.

Итак, есть ли способ нацелить все термины, которые будут обмениваться более эффективно и легко, или лучший способ сделать это? Я могу работать только с клиентскими решениями, поэтому нет PHP и так далее.

Спасибо заранее и, надеюсь, это было не так уж долго, чтобы читать.

+0

Я должен признать, так как я новый к более глубокому HTML и полностью к Javascript. Я этого не знал, потому что W3C Schools начинается с HTML 4.;) Что касается обратной совместимости. Спекуляции говорят, что он должен работать с IE 7 или Firefox 3.5 (и позже, конечно). Я нахожу противоречивую информацию о HTML 5 и старых браузерах. –

ответ

4

Вы можете использовать атрибуты данных: факт, что «атрибуты HTML5 не поддерживаются в IE6 и IE7» означает, что вы не получаете метод getAttribute() или свойство dataset для получения/доступа к ним. Но вы все равно можете восстановить их, как описано в this post.

<div id="geoff" data-geoff="geoff"> 
var geoff = document.getElementById("geoff"); 
alert(geoff.getAttribute("data-geoff")); 

Даже лучше, вы можете использовать JQuery .data() для поддержки предыдущих версий IE.

Что-то вдоль этих линий должно работать:

<div data-translate="translation_key"></div> 
$("[data-translate]").each(function(){ 
    var key = $(this).data('translate'); 
    $(this).html(dictionary[key][current_lang] || "N/A"); 
}); 

Рабочий пример: https://jsfiddle.net/x93oLad8/4/

+0

Обратите внимание, что 'data' jQuery работает только с json-кодированными значениями, поэтому вам нужно будет указывать и избегать содержимого атрибута данных в этом случае (что не так удобно при работе со скалярными значениями). –

+0

Ну, спасибо за указание на это, но я думаю, что это не будет ограничением в этом случае, поскольку ключи перевода должны быть простыми буквенно-цифровыми строками, возможно с подчеркиванием в качестве разделителя и не нуждаться в каком-либо специальном экранировании. –

+0

Извините, я проверил [docs] (https://api.jquery.com/data/#data-html5), и я ошибаюсь. Значения строк загружаются как есть, вам не нужно их кодировать в JSON. –

2

Один из способов обойти это было бы использовать какую-то систему шаблонного на стороне клиента для ваш интерфейс. Таким образом, вам не нужно излишне загружать свой HTML с кучей атрибутов данных, подробно описывающих требования к языку, но просто описывайте его один раз в JavaScript и используйте несколько функций для оказания помощи при переводе. Я привел быстрый пример ниже, чтобы показать вам, что я имею в виду.

Это объект словаря. Он содержит все переводы по странам.Это означает, что вам не нужны отдельные словари для каждой страны. Это важно, потому что это означает, что мы можем использовать эту структуру одного объекта очень легко в функции перевода, как вы увидите через мгновение. Это также означает, что вы можете добавить столько языков и переводов, сколько захотите.

var dict = { 
    en: { 
     'Hallo': 'Hallo', 
     'Goodbye': 'Goodbye', 
     'castle': 'castle' 
    }, 
    fr: { 
     'Hallo': 'Bonjour', 
     'Goodbye': 'Au revoir', 
     'castle': 'chateau' 
    }, 
    de: { 
     'Hallo': 'Hallo', 
     'Goodbye': 'Auf Wiedersehen', 
     'castle': 'schloss' 
    } 
} 

Это наш код страны и относится непосредственно к ключу с кодом страны в нашем словаре объекта:

var lang = 'fr'; 

Первый из наших двух функций. Это берет шаблон и язык и выполняет перевод, возвращая все, что осталось (как правило, какой-то HTML, как в нашем примере).

function applyTemplate(tmpl, lang) { 

    // find all words within {{word}} a double set of curly braces 
    // (this format is similar to the handlebars templating engine) 
    var regex = /\{\{([a-zA-Z])\w+\}\}/g 

    // for each found word perform the translation and 
    // remove the curly braces 
    return tmpl.replace(regex, function (word) { 
     return translate(dict, lang, word.replace(/[\{\}]/g, '')); 
    }); 
} 

Функция перевода выполняет словарь, язык и слово и возвращает переведенное слово. Обратите внимание, что это намного проще с одним объектом, содержащим все переводы по стране.

function translate(dict, lang, word) { 
    return dict[lang][word]; 
} 

Некоторые HTML. Вот наш шаблон (display: none) и выходной элемент. Обратите внимание, что слова в фигурных скобках - это те, которые нужно перевести.

<div class="template"><div>{{Goodbye}}, {{castle}}</div></div> 
<div id="translation"><div> 

Наконец, положить все это вместе:

// grab the template 
var tmpl = document.querySelector('.template').textContent; 
var translation = document.querySelector('#translation'); 

// grab our translated html and add it to the output element 
var html = applyTemplate(tmpl, lang); 
translation.insertAdjacentHTML('afterbegin', html); 

DEMO

Теперь, очевидно, вы не должны использовать этот метод (есть десятки JS шаблонных двигателей там), но templating особенно полезен для сайтов, которым необходимо использовать несколько языков. Многие делают это на задней стороне, но, как вы можете видеть, его также можно легко сделать на стороне клиента.

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

11

Не обижайтесь другим ответчикам, но сохраняйте текст в JavaScript или атрибуты данных, не подходит для поисковых систем или отключенных посетителей сайта и не предлагает никаких преимуществ при добавлении излишне сложного кода. На мой взгляд, лучшим и самым простым решением является использование атрибута HTML lang и использование JavaScript для отображения и скрытия желаемого языка. Это решение также изящно деградирует, поэтому, если посетитель сайта отключил JavaScript, он все равно отобразит контент. Вот мое решение:

HTML

<button id="switch-lang">Switch Language</button> 

<h1><span lang="en">Hello</span> <span lang="es">Hola</span></h1> 

<p lang="en">I really enjoy coding.</p> 

<p lang="es">Me gusta mucho la codificación.</p> 

JQuery

$('[lang="es"]').hide(); 

$('#switch-lang').click(function() { 
    $('[lang="es"]').toggle(); 
    $('[lang="en"]').toggle(); 
}); 

Тогда я бы рекомендовал добавлять HTML5 Geolocation, чтобы определить, какой язык, чтобы показать первоначально на основе местоположения пользователей в Мир.Я хотел бы также использовать значок Fontawesome языка, чтобы показать пользователям, они могут переключать языки в пути, который понятен любому: http://fontawesome.io/icon/language/

Вот рабочий пример кода на CodePen: https://codepen.io/codepajamas/pen/ZejaQz?editors=1010

Вот дополнительный пример на коде пера с помощью выбора меню для переключения между 3 (или более) языках: https://codepen.io/codepajamas/pen/NjGOMV

Обновлено Полный пример с геолокации и Cookies

я продолжал работать на этом и создал обновленный пример переключения между двумя языками на китайском и английском языках (если вам нужно больше двух языков, вам нужно будет скрыть все языки и показать только тот, который был выбран, вместо того, чтобы переключать то, как я есть). Этот код также определяет, установлен ли уже существующий файл cookie для языка с использованием jQuery Cookie. Он также проверяет свою геолокацию, если их браузер поддерживает ее, автоматически устанавливая язык на китайский, если они находятся в Тайване или Китае и по умолчанию на английском языке во всех других странах. Код ниже прокомментирован, поэтому вы можете видеть, что делает каждый шаг, и, надеюсь, он сможет его модифицировать в соответствии с вашими потребностями. Вот оно:

HTML

<button id="switch-lang">Switch Language Icon Here</button> 

<h1><span lang="en">Hello</span> <span lang="zh">你好</span></h1> 

<p lang="en">I really enjoy coding.</p> 

<p lang="zh">我真的很喜歡編碼。</p> 

JQuery Примечание: это требует увязки не только jQuery но jQuery Cookie

$(function() { 
    ///// Language Switching (2 languages: English and Chinese). ///// 

    // Initially disable language switching button. 
    $('#switch-lang').css({'pointer-events':'none', 
    'cursor':'default'}).attr('disabled','disabled'); 

    function langButtonListen() { 
    $('#switch-lang').click(function (event) { 
     event.preventDefault(); 
     $('[lang="zh"]').toggle(); 
     $('[lang="en"]').toggle(); 
     // Switch cookie stored language. 
     if ($.cookie('lang') === 'en') { 
     $.cookie('lang', 'zh', { expires: 7 }); 
     } else { 
     $.cookie('lang', 'en', { expires: 7 }); 
     } 
    }); 
    // Enable lang switching button. 
    $('#switch-lang').css({'pointer-events':'auto', 
    'cursor':'pointer'}).removeAttr('disabled'); 
    } 

    // Check if language cookie already exists. 
    if ($.cookie('lang')) { 
    var lang = $.cookie('lang'); 
    if (lang === 'en') { 
     $('[lang="zh"]').hide(); 
     langButtonListen(); 
    } else { 
     $('[lang="en"]').hide(); 
     langButtonListen(); 
    } 
    } else { 
    // no cookie set, so detect language based on location. 
    if ("geolocation" in navigator) { 
     // geolocation is available 
     navigator.geolocation.getCurrentPosition(function (position) { 
     // accepted geolocation so figure out which country 
     var lat = position.coords.latitude, 
      lng = position.coords.longitude; 
     $.getJSON('http://maps.googleapis.com/maps/api/geocode/json?latlng='+lat+','+lng+'&sensor=true', null, function (response) { 
      var country = response.results[response.results.length-1].formatted_address; 
      if (country === 'Taiwan' || country === 'China') { 
      $('[lang="en"]').hide(); 
      $.cookie('lang', 'zh', { expires: 7 }); 
      langButtonListen(); 
      } else { 
      $('[lang="zh"]').hide(); 
      $.cookie('lang', 'en', { expires: 7 }); 
      langButtonListen(); 
      } 
     }).fail(function (err) { 
      console.log('error: '+err); 
      $('[lang="zh"]').hide(); 
      $.cookie('lang', 'en', { expires: 7 }); 
      langButtonListen(); 
     }); 
     }, 
     function (error) { 
     if (error.code == error.PERMISSION_DENIED) { 
      // denied geolocation 
      $('[lang="zh"]').hide(); 
      $.cookie('lang', 'en', { expires: 7 }); 
      langButtonListen(); 
     } else { 
      console.log('Unknown error. Defaulting to English!'); 
      $('[lang="zh"]').hide(); 
      $.cookie('lang', 'en', { expires: 7 }); 
      langButtonListen(); 
     } 
     }); 
    } else { 
     // geolocation IS NOT available 
     $('[lang="zh"]').hide(); 
     $.cookie('lang', 'en', { expires: 7 }); 
     langButtonListen()); 
    } 
    } 
}); 
+1

Это очень приятное решение! –

Смежные вопросы