用于翻译的自定义 vanilla JS 在 Android Chrome 上不起作用

Posted

技术标签:

【中文标题】用于翻译的自定义 vanilla JS 在 Android Chrome 上不起作用【英文标题】:Custom vanilla JS for translation does not work on Android Chrome 【发布时间】:2020-11-14 21:25:56 【问题描述】:

我一直在努力使用任何(实际上是任何!)客户端(例如网络浏览器)翻译库。测试了几个:jquery-i18next、jquery.i18n、localizejs、translate-js。猜猜看 - 没有一个真正按预期工作,没有一个只是一个即插即用的解决方案。这就是为什么我决定编写一个普通的 javascript 代码作为最简单的替代方案。代码如下:

let locale;

let dict = 
  'en': ...,
  'fr': ...
;

function detectNavigatorLocale() 
  const languageString = navigator.language || '';
  const language = languageString.split(/[_-]/)[0].toLowerCase();

  switch (language) 
    case 'en':
      return 'en';
    case 'de':
      return 'de';
    default:
      return 'en';
  


// replacement to $(document).ready() in jQuery
function docReady(fn) 
  // see if DOM is already available
  if (document.readyState === "complete" || document.readyState === "interactive") 
    // call on next available tick
    setTimeout(fn, 1);
   else 
    document.addEventListener("DOMContentLoaded", fn);
  


// helper to get nested value in JSON-like object by dot-path string
function findProp(obj, prop, defval) 
  if (typeof defval == 'undefined') defval = null;
  prop = prop.split('.');
  for (var i = 0; i < prop.length; i++) 
    if (typeof obj[prop[i]] == 'undefined')
      return defval;
    obj = obj[prop[i]];
  
  return obj;


let switchers = document.querySelectorAll('[data-locale]');

for (let i = 0; i < switchers.length; i++) 
  switchers[i].onclick = function () 
    let newLocale = switchers[i].getAttribute('data-locale');
    locale = newLocale;
    translate();
  ;


function translate(newLocale) 
  let els = document.querySelectorAll('[data-i18n]');

  for (let i = 0; i < els.length; i++) 
    let path = els[i].getAttribute('data-i18n');
    let translatation = findProp(dict[locale], path, 'undefined');
    els[i].innerhtml = translatation;
  

  // trigger repainting
  window.dispatchEvent(new Event('resize'));
;


docReady(function () 
  locale = detectNavigatorLocale();
  translate();
);

为了让它工作,在 HTML 中唯一要做的就是将属性添加到需要翻译为 &lt;p data-i18n="some.path.in.dictionary"&gt;fallback text&lt;/p&gt; 的元素。要更改我使用的语言 &lt;li data-locale="en"&gt;EN&lt;/li&gt; 和类似的。

但这里有一个棘手的部分:为什么桌面浏览器显示预期结果,但几个经过测试的移动浏览器拒绝 a)在区域设置切换器元素上发出事件 b)在某些(Brave,Dolphin)中,即使处于折叠状态的导航栏也不会展开.我希望后者通常与所选浏览器中的 JS 处理有关,但为什么在 Chrome 中相同的代码不起作用?

【问题讨论】:

【参考方案1】:

首先,我将设置onclick 的不良做法替换为以下内容:

function switchLocale(loc) 
    locale = loc;
    translate();


let switchers = document.querySelectorAll('[data-locale]');

switchers.forEach(
    function(switcher) 
        switcher.addEventListener("click", function() 
            // alert(switcher.id);
            switchLocale(switcher.getAttribute('data-locale'));
        )
    
)

并测试它工作正常。但实际的问题是z-index 太低了,下图叠加在移动导航上方。 :)

【讨论】:

以上是关于用于翻译的自定义 vanilla JS 在 Android Chrome 上不起作用的主要内容,如果未能解决你的问题,请参考以下文章

JS Uncaught TypeError:无法读取未定义的属性(vanilla js)

Quartz 第二课 Jobs and Triggers(官方文档翻译)

用于 nuxt.js 构建的自定义 index.html

来自 MYSQL PDO 的自定义格式 JSON,用于 NVD3.js

Vue indexOf vs vanilla javascript用于从数组中选择对象

尝试在 Vanilla JS 中创建 Web 组件库,你会如何开始?