web-dev-qa-db-ja.com

JavaScriptを使用してWebサイトの言語を変更する

複数の言語を使用できるGUI Webサイトで作業しています。私が作業するようになった元のHTMLファイルは完全に静的でした。したがって、翻訳が必要な場合は、すべてのファイルを解析し、いくつかの単語や用語がどこにあるかをメモし、それらをすべて収集して翻訳部門に渡し、それらの翻訳を新しい言語ファイルに入力する必要がありました。

これらのファイルは完全に静的であるため、セクション全体を数回翻訳する必要がありました。あまり効率的ではありません。

それで今、私はそれらのウェブサイトで用語を交換するために、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_#"as識別子。辞書タグにスライスし、次のコードと交換します。

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を操作するには、同じ用語を各言語に1回、数回タグ付けする必要があります。

それで、すべての用語をより効率的かつ簡単に交換するための方法、またはそれを行うためのより良い方法はありますか?私はクライアント側のソリューションでしか作業できないため、PHPなど。

事前に感謝し、願わくばこれが長すぎないことを願っています。

14
Blind Seer

データ属性を使用できます。「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/

6
Andrea Casaccia

他の回答者に不快感を与えることはありませんが、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=101

選択メニューを使用して3つ(またはそれ以上)の言語を変更するコードペンの追加例を次に示します。 https://codepen.io/codepajamas/pen/NjGOMV

位置情報とクッキーを含む完全な例を更新

私はこれに取り組み続け、中国語と英語の2つの言語を切り替える更新された例を作成しました(2つ以上の言語が必要な場合は、トグルを使用する代わりにすべての言語を非表示にし、選択した言語のみを表示する必要があります)。このコードは、jQuery Cookieを使用して、既存の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());
    }
  }
});
24
J Grover

これを回避する方法の1つは、インターフェイスに何らかのクライアント側テンプレートシステムを使用することです。そうすれば、言語要件を詳述する一連のデータ属性を不必要にHTMLにロードする必要はありませんが、JavaScriptで一度記述し、いくつかの関数を使用して翻訳を支援するだけです。私が意味することを示すために、以下の簡単な例をコーディングしました。

これが辞書オブジェクトです。国コード別の翻訳allが含まれています。つまり、国ごとにseparate辞書は不要です。これは重要です。というのは、すぐにわかるように、この単一のオブジェクト構造を翻訳機能で非常に簡単に使用できるからです。また、必要な数の言語と翻訳を追加できることも意味します。

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';

2つの関数の最初。これはテンプレートと言語を取り、翻訳を実行して、残っているものを返します(通常、この例のような何らかの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関数は、辞書、言語、およびWordを受け取り、翻訳されたWordを返します。 1つのオブジェクトにすべての国の翻訳が含まれていると、これがはるかに簡単になることに注意してください。

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

いくつかのHTML。これがテンプレート(表示:なし)と出力要素です。中括弧内の単語は翻訳されるものであることに注意してください。

<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テンプレートエンジンがあります)が、テンプレートは特にサイトに便利です複数の言語を使用する必要があります。多くはバックエンドでこれを行いますが、ご覧のとおり、クライアント側でも簡単に行うことができます。

これが有用であり、ソリューションにどのようにアプローチするかについてのいくつかの異なるアイデアが与えられたことを願っています。

3
Andy
 <script type="text/javascript">

// Google Transliteration APIを読み込みますgoogle.load( "elements"、 "1"、{packages: "transliteration"});

  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);
0
Priyabrat Rath