Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

this.nextSibling not working

I expect the following code to alert "out"

<input type=text onfocus="alert(this.nextSibling.id)" />
<output id="out">this is output</output>

But it alerts undefined WHY?

like image 527
moroccan_dev Avatar asked Nov 15 '14 11:11

moroccan_dev


Video Answer


3 Answers

nextSibling selects the very next sibling node of the element. The very next node can also be a textNode which doesn't have an id property, hence you get the undefined value. As the other answer suggests you could use the nextElementSibling property which refers to the next sibling node that has nodeType of 1 (i.e. an Element object) or remove the hidden characters between the elements.

Note that IE8 doesn't support the nextElementSibling property.

like image 120
undefined Avatar answered Oct 09 '22 22:10

undefined


Try this:

alert(this.nextElementSibling.id);

NOTE: The nextSibling property returns the node immediately following the specified node, in the same tree level.

The nextElementSibling read-only property returns the element immediately following the specified one in its parent's children list, or null if the specified element is the last one in the list.

like image 11
Johan Karlsson Avatar answered Oct 09 '22 23:10

Johan Karlsson


Why you have this problem

nextSibling selects the next sibling node of the element. In your case you have a text node as a next node because you have a new line between your element nodes. Each text node between element nodes will be selected as next node and this nodes don't have an id property.

To prevent this we can use 2 ways:

Solution 1:

We delete a new lines, all of whitespaces, comment nodes or other text nodes and then we can use nextSibling:

<input type="button" value="get next sibling value" onclick="console.log(this.nextSibling.value)"><input type="text" value="txt 1">

Solution 2:

We use instead of nextSibling the nextElementSibling property:

<input type="button" value="get next sibling value" onclick="console.log(this.nextElementSibling.value)">
<input type="text" value="txt 1">

The nextElementSibling property returns the element immediately following the specified one in its parent's children list, or null if the specified element is the last one in the list.

In the case if some browser like IE8 doesn't support the nextElementSibling property we can use a polyfill (it should be placed before your code):

if(!('nextElementSibling' in document.documentElement))
{
    Object.defineProperty(Element.prototype, 'nextElementSibling',
    {
        get: function()
        {
            var e = this.nextSibling;
            while (e && e.nodeType !== 1)
                e = e.nextSibling;

            return e;
        }
    });
}

Relevant links:

  • Node.nextSibling

  • NonDocumentTypeChildNode.nextElementSibling

like image 5
Bharata Avatar answered Oct 09 '22 22:10

Bharata