2016-02-16 134 views
0

假设你有一个HTML页面,其中包含不同语言的部分,这样的隐含lang属性:获取一个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

+0

'element.lang'将让你的'lang'属性值,似乎是相当直接的。或者你的意思是,如果孩子的元素没有父母,你是否需要父母? –

+0

您可以使用选择器(如您所见)来获取具有lang属性的元素。对于任何特定节点,您可以使用[* contains *](https://developer.mozilla.org/en/docs/Web/API/Node/contains)方法来查看它是否是任何特定节点的后代。你的代码看起来很复杂,可以大大简化。请注意,在IE 8中'[] .slice.call(hostObject)'将失败。 – RobG

+2

在最新的Chrome和Firefox中,整个函数只是'element.closest('[lang]')。lang' – adeneo

回答

1

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

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>

+1

更有效地使用IIFE来生成*元素*并在封闭中保留引用,所以您不必每次都创建它。但是,对DOM的更新可能会使其复杂化。 – RobG

+0

@RobG它基本上是元素数组的单例,如你所说,它不会反映DOM的更新。当然有益,但对于这种用例可能有点复杂。 –