Suppose you have an HTML page that contains sections in different languages, like this:
<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">Explicitly Aussie</p>
</html>
Is there a direct way to discover which particular language code applies to a given HTML element? Something like:
// pseudo-code
var lang = myElement.getLang()
Here's what appears to be a very roundabout solution:
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
}
Is there a more obvious way? jsFiddle
A much simpler answer: element.closest('[lang]').lang
.
element.closest(selector)
will return the first matching ancestor of element
that matches the CSS selector selector
, or element
itself if it matches selector
.
Demo:
const dn = new Intl.DisplayNames('en-US', { type: 'language' })
document.body.addEventListener('mouseover', (event) => {
for (const el of document.querySelectorAll('[lang]')) {
el.style.background = 'white'
}
const localized = event.target.closest('[lang]')
localized.style.background = '#cdf'
document.querySelector('#lang-output').textContent = dn.of(localized.lang)
})
<body lang="en">
<div style="color: firebrick; font-weight: bold;">
<code>
Language of currently hovered content:
<span id="lang-output">[none]</span>
</code>
</div>
<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">Explicitly Aussie</p>
</body>