Использование Javascript для изменения языка веб-сайта


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

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

Итак, теперь я я работаю над каким-то словарем на 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;
}
}

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

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

Заранее благодарю и надеюсь, что это не было слишком долго, чтобы читать.

4 9

4 ответа:

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

<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/

Не обижайтесь на других ответчиков, но хранение текста в 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

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

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

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());
    }
  }
});

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

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

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, ''));
    });
}
Функция translate принимает словарь, язык и Слово и возвращает переведенное слово. Обратите внимание, что это гораздо проще, если один объект содержит все переводы страны.
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);

Демо

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

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

 <script type="text/javascript">

/ / Загрузите Google Transliteration API гугл.нагрузка ("элементы", " 1", { пакеты: "транслитерация" });

  var transliterationControl;
  function onLoad() {
    var options = {
        sourceLanguage: 'en',
        destinationLanguage: ['hi','or','bn','ta','te'],
        transliterationEnabled: true,
        shortcutKey: 'ctrl+g'
    };
    // Create an instance on TransliterationControl with the required
    // options.
    transliterationControl =
      new google.elements.transliteration.TransliterationControl(options);

    // Enable transliteration in the textfields with the given ids.
    var ids = [ "transl1", "transl2" ];
    transliterationControl.makeTransliteratable(ids);

    // Add the STATE_CHANGED event handler to correcly maintain the state
    // of the checkbox.
    transliterationControl.addEventListener(
        google.elements.transliteration.TransliterationControl.EventType.STATE_CHANGED,
        transliterateStateChangeHandler);

    // Add the SERVER_UNREACHABLE event handler to display an error message
    // if unable to reach the server.
    transliterationControl.addEventListener(
        google.elements.transliteration.TransliterationControl.EventType.SERVER_UNREACHABLE,
        serverUnreachableHandler);

    // Add the SERVER_REACHABLE event handler to remove the error message
    // once the server becomes reachable.
    transliterationControl.addEventListener(
        google.elements.transliteration.TransliterationControl.EventType.SERVER_REACHABLE,
        serverReachableHandler);

    // Set the checkbox to the correct state.
    document.getElementById('checkboxId').checked =
      transliterationControl.isTransliterationEnabled();

    // Populate the language dropdown
    var destinationLanguage =
      transliterationControl.getLanguagePair().destinationLanguage;
    var languageSelect = document.getElementById('languageDropDown');
    var supportedDestinationLanguages =
      google.elements.transliteration.getDestinationLanguages(
        google.elements.transliteration.LanguageCode.ENGLISH);
    for (var lang in supportedDestinationLanguages) {
      var opt = document.createElement('option');
      opt.text = lang;
if (lang=="TAMIL" || lang=="TELUGU" || lang=="HINDI" || lang=="ORIYA" || lang=="BENGALI"){
      opt.value = supportedDestinationLanguages[lang];
      if (destinationLanguage == opt.value) {
        opt.selected = true;
      }
      try {
        languageSelect.add(opt, null);
      } catch (ex) {
        languageSelect.add(opt);
      }
}//End of if
    }
  }

  // Handler for STATE_CHANGED event which makes sure checkbox status
  // reflects the transliteration enabled or disabled status.
  function transliterateStateChangeHandler(e) {
    document.getElementById('checkboxId').checked = e.transliterationEnabled;
  }

  // Handler for checkbox's click event.  Calls toggleTransliteration to toggle
  // the transliteration state.
  function checkboxClickHandler() {
    transliterationControl.toggleTransliteration();
  }

  // Handler for dropdown option change event.  Calls setLanguagePair to
  // set the new language.
  function languageChangeHandler() {
    var dropdown = document.getElementById('languageDropDown');
    transliterationControl.setLanguagePair(
        google.elements.transliteration.LanguageCode.ENGLISH,
        dropdown.options[dropdown.selectedIndex].value);
  }

  // SERVER_UNREACHABLE event handler which displays the error message.
  function serverUnreachableHandler(e) {
    document.getElementById("errorDiv").innerHTML =
        "Transliteration Server unreachable";
  }

  // SERVER_UNREACHABLE event handler which clears the error message.
  function serverReachableHandler(e) {
    document.getElementById("errorDiv").innerHTML = "";
  }
  google.setOnLoadCallback(onLoad);