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?
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With