2016-02-16 166 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的更新。當然有益,但對於這種用例可能有點複雜。 –