【问题标题】:Get the implicit lang attribute of an HTML element获取 HTML 元素的隐式 lang 属性
【发布时间】:2016-02-16 20:26:47
【问题描述】:

假设您有一个 HTML 页面,其中包含不同语言的部分,如下所示:

<html lang=en>
<div lang="th">
  <p id="test1">ไทย</p>
</div>
<p id="test2">Implicitly English</p>
<div lang="en-CA">
  <p id="test3">As Canadian as possible under the circumstances</p>
</div>
<p lang="en-AU"id="test4">Explictly Aussie</p>
</html>

是否有直接的方法来发现特定的语言代码适用于给定的 HTML 元素?比如:

// pseudo-code
var lang = myElement.getLang()

这似乎是一个非常迂回的解决方案:

function getLang(element) {
  var lang = element.getAttribute("lang")

  if (!lang) {
    var elements
      , languages
      , language
      , ii
      , selector

    // Find all elements with an explicit lang attribute
    elements = [].slice.call(document.querySelectorAll("*[lang]"))

    // Determine which languages are present
    languages = []
    for (ii in elements) {
      lang = elements[ii].getAttribute("lang")
      if (languages.indexOf(lang) < 0) {
        languages.push(lang)
      }
    }

    lang = "" // reset

    for (ii in languages) {
      language = languages[ii]
      selector = ":lang(" + language + ")"
      elements = [].slice.call(document.querySelectorAll(selector))

      if (elements.indexOf(element) > -1) {
        if (lang.length < language.length) {
          lang = language
        }
      }
    }
  }

  return lang
}

还有更明显的方法吗? jsFiddle

【问题讨论】:

  • element.lang 会给你lang 属性值,看起来很直接。或者如果子元素没有,你的意思是得到一个父母语言?
  • 您可以使用选择器(如您所用)来获取具有 lang 属性的元素。对于任何特定节点,您可以使用contains 方法来查看它是否是任何特定节点的后代。您的代码看起来很复杂,可以大大简化。请注意,[].slice.call(hostObject) 在 IE 8 中将失败。
  • 在最新的 Chrome 和 Firefox 中,整个功能将只是 element.closest('[lang]').lang

标签: javascript iso lang


【解决方案1】:

我用下面的代码更新了你的小提琴,你可以在这个 sn-p 中运行它。这大大简化了它。

function getLang(elem) {
  var lang = "";
  if (elem) {
    var elements = [];
    var queryResult = document.querySelectorAll("[lang]");
    try {
      //Wrapping in a try catch block to handle unsupported browsers.
      elements = [].slice.call(queryResult);
    } catch (error) {
      for (var i = 0, len = queryResult.length; i < len; i++) {
        elements.push(queryResult[i]);
      }
    }
    if (elements.length > 0) {
      //Find in the NodeList where the element is either itself or the first parent with lang attribute of the given element.
      var matches = elements.filter(function(e) {
        return e === elem || e.contains(elem);
      }); //ES2015 -> elements.filter(e => e === elem || e.contains(elem));
      var match = matches.length > 0 ? matches[matches.length - 1] : matches[0];
      lang = match.lang ? match.lang : lang;
    }
  }
  return lang;
}

var result = getLang(document.querySelector("#test1")) + " ";
result += getLang(document.querySelector("#test2")) + " ";
result += getLang(document.querySelector("#test3")) + " ";
result += getLang(document.querySelector("#test4"));

alert(result);
<body lang=en>
  <div lang="th">
    <p id="test1">ไทย</p>
  </div>
  <p id="test2">Implicitly English</p>
  <div lang="en-CA">
    <p id="test3">As Canadian as possible under the circumstances</p>
  </div>
  <p lang="en-AU" id="test4">Explictly Aussie</p>
</body>

【讨论】:

  • 使用 IIFE 生成 元素 并在闭包中保留引用会更有效,这样您就不必每次都创建它。但是,对 DOM 的更新可能会使这变得复杂。
  • @RobG 它本质上是元素数组的单例,正如您所说,它不会反映对 DOM 的更新。当然是有益的,但对于这个用例来说可能有点太复杂了。
  • 这可能很明显,但为什么不只是 document.querySelector('[lang]').attributes.lang.value 并将值推送到数组中呢?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-01
  • 1970-01-01
  • 2021-04-17
  • 1970-01-01
  • 2019-11-30
  • 1970-01-01
相关资源
最近更新 更多