this.nextSibling not working

2019-04-19 18:10发布

问题:

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?

回答1:

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.



回答2:

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.



回答3:

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



回答4:

Assuming that you can use jQuery

Note that this.nextSibling might not work in IE specifically

The jQuery alternative for this.nextSibling is $(this).next()