5

According to the spec, language is inherited from the nearest ancestor element which has lang set. So how do I get the language of one of these descendents?

I'm setting the language with the lang attribute:

<div id="outer" lang="es">
    <div id="inner">¿Por qué?</div>
</div>

And trying to access it with the lang property:

alert(document.getElementById('outer').lang);
alert(document.getElementById('inner').lang);

I pretty quickly noticed that the lang property of the inner div isn't the inherited language (or it's not inheriting; no idea). This fiddle demonstrates the behavior I'm seeing.

How can I determine an element's language with Javascript? I'm really looking to take advantage of the inheritance of the lang attribute, as I also need this to work with screen-readers.

4
  • 2
    You'll have to traverse the DOM tree to find it. Commented Feb 11, 2015 at 19:49
  • Assuming the lang attribute is even set. Commented Feb 11, 2015 at 19:50
  • 2
    Just because a DOM element inherits behavior from an ancestor, does not mean it has the property set on itself. Commented Feb 11, 2015 at 19:53
  • jsfiddle.net/sv96aLh1/3 Commented Feb 11, 2015 at 19:54

2 Answers 2

3

From the very spec you linked to:

To determine the language of a node, user agents must look at the nearest ancestor element (including the element itself if the node is an element) that has a lang attribute in the XML namespace set or is an HTML element and has a lang in no namespace attribute set. That attribute specifies the language of the node (regardless of its value).

Inheriting from another element doesn't mean the attribute is set for the element itself. Therefore, your code must, as well, find the nearest parent with the lang attribute (if any exist). See this question if that sounds problematic.

Sign up to request clarification or add additional context in comments.

2 Comments

The OP needs to use hasAttribute to determine if an element has the lang attribute. I guess if (typeof element.getAttribute('lang') == 'string') might do the job also.
I was really hoping that that actual user agent (the browser) would be able to do this for me.
1

Here is a function that will return the value of the "lang" attribute of the nearest ancestor of any element, or undefined if none is found:

function elementLang(el) {
  while (el) {
    if (el.hasAttribute('lang')) {
      return el.getAttribute('lang');
    }
    el = el.parentElement;
  }
}

// From your example jsFiddle...
elementLang(document.getElementById('inner')); // => "es"
elementLang(document.getElementById('outer')); // => "es"
elementLang(document.getElementById('output')); // => undefined

8 Comments

This would be a better solution if you made it iterative instead of recursive. Recursion is generally slow and there's no need to use it here.
So iteration is better than recursion?
Simple iteration is generally certainly faster, you simply can't always use it to achieve what you want in a reasonable manner.
What about tail recursion on tail-call-optimizing interpreters or compilers?
See the second half of my comment.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.