16

I have a pure Javascript script with an onclick event that checks the value of the next sibling before deciding what to do. This will cause an error if the element clicked is the last element in its container (because of accessing nextSibling). I need to first check that the element clicked is not the last element in the container, but can't seem to find out how.

Note: I don't think this is a duplicate. There are quite a few questions about checking if an element is the last child, but all accepted answers—all answers in general—use JQuery.

Joseph Hansen
  • 12,665
  • 8
  • 50
  • 68
  • You probably thought about this already but why not use jQuery? Chances are it will come in handy not only here but in many other places in your project. – Jon Doe Apr 13 '15 at 18:01
  • Can you show us some code. – Jonathan Apr 13 '15 at 18:08
  • nextSibling returns `null`, couldn't you check for that? e.g. `if (el.nextSibling != null) { //do this }` – simpleManderson Apr 13 '15 at 18:11
  • @simpleManderson Yep... so... now I am embarrassed. I have all of these answers and it turns out I was just testing the deployed code instead of the dev code. I was checking `nextSibling` correctly before asking the question but didn't see that it was working. – Joseph Hansen Apr 13 '15 at 18:15
  • 1
    @Joseph Actually you can't rely on `nextSibling`, if you need an _element_. To detect an element you would use `nextElementSibling`, which is guaranteed to give you an _element_ (or `null` if there's no element), not a text node or a comment. – Teemu Apr 13 '15 at 18:17

11 Answers11

21

You can use the .nextSibling property on the element and see if it comes back as empty (undefined, etc).

El Guapo
  • 5,581
  • 7
  • 54
  • 82
4

You can use the node.lastChild Property

The Node.lastChild read-only property returns the last child of the node. > If its parent is an element, then the child is generally an element node, > a text node, or a comment node. It returns null if there are no child elements..

var tr = document.getElementById("row1");
var corner_td = tr.lastChild;
Seth
  • 10,198
  • 10
  • 45
  • 68
Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331
  • 3
    @MarcoBonelli yet much more fitting to the problem at hand. – Jonathan Apr 13 '15 at 18:06
  • @Jonathan I don't think so: using the next sibling property will be faster, and you can check whether an element has a next sibling just with an `if` statement. The OP wants to check if an element has a next sibling, and, if so, use it. – Marco Bonelli Apr 13 '15 at 18:07
  • OP asks for a way to check if an element is last child. But I agree he probably just misses a null check, which is why I've asked for some code. – Jonathan Apr 13 '15 at 18:12
  • 2
    `element === element.parentNode.lastChild` – ESR Jul 26 '18 at 13:14
3

The error you get should be some kind of can't set property on undefined.

You have just to check whether the next element exists:

if (typeof element.nextSibling === "undefined")
    return;
Al.G.
  • 4,327
  • 6
  • 31
  • 56
  • 1
    It's easier and faster to check for `element.nextSibling === null` – Lukas Jun 12 '15 at 12:14
  • 2
    @Lukas you could even do `if(!element.nextSibling)`, if you want. Take a look at this - http://stackoverflow.com/q/5076944/3132718 – Al.G. Jun 12 '15 at 17:13
3

For some reason none of the answers worked for me, I always ended up seeing a #text node instead of undefined or null, so I ended up comparing my element with the last child of the parent of the element:

element === element.parentNode.children[element.parentNode.children.length-1] 

or if you want it as a function

function isLastChild(el) {
  return (el === el.parentNode.children[el.parentNode.children.length-1]) 
}

//Useage
if(isLastChild(el)) {
  //Element is the last child of its parent.
}

Might be longer than other answers but surly won't fail you.

Art3mix
  • 1,276
  • 7
  • 18
1

This is one way to check:

document.querySelector(":last-child");

Here's one more:

var isLastChild = (element === element.parentNode.lastChild);
Jonathan
  • 8,771
  • 4
  • 41
  • 78
1

If you're trying to make this compatible with older browsers, just use childNodes:

// Last element in the body
document.getElementsByTagName('body')[0].childNodes[document.getElementsByTagName('body')[0].childNodes.length-1]

so for your particular problem, use the event object in your onclick:

element.onclick = function(event) {
    var parent = event.target.parentNode;
    if(event.target === parent.childNodes[parent.childNodes.length-1])
        // Code here
}
Alex W
  • 37,233
  • 13
  • 109
  • 109
1

Accessing an element's nextSibling element you'll get null if the element has no next sibling, so you can just check before going on with your code, like this:

if (myElement.nextSibling) {
    // the element has a next sibling
    // go on...
} else {
    // the element is the last child
}
Marco Bonelli
  • 63,369
  • 21
  • 118
  • 128
1

Use the .lastChild property of the node.

Example:

Here, we are removing last 4 child nodes in the list.

function clearAll() {
    var sidemenu = document.getElementById('side_menu');
    
    console.log("sidemenu.childNodes.length = " + sidemenu.childNodes.length);

    while (sidemenu.childNodes.length > 2) {
        console.log(sidemenu.childNodes);
        sidemenu.removeChild(sidemenu.lastChild);
        console.log("removed");
        console.log("sidemenu.childNodes.length = " + sidemenu.childNodes.length);
    }
    
    console.log("What we have left now:");
    console.log(sidemenu.childNodes);
}

clearAll();
<ul id="side_menu">
    <li>List Item 1</li>
    <li>List Item 2</li>
    <li>List Item 3</li>
    <li>List Item 4</li>
    <li>List Item 5</li>
</ul>

Learn more: Node.lastChild - Web API Interfaces | MDN

Rahul Desai
  • 15,242
  • 19
  • 83
  • 138
  • Reading the docs "... the child is generally an element node, a text node, or a comment node." --> this property is not reliable when trying to detect the last child element (This stands for `nextSibling` too) . – Teemu Apr 13 '15 at 18:06
1

How about var isLastChild = element === element.parentNode.lastChild?

tetri
  • 3,753
  • 2
  • 25
  • 37
ESR
  • 1,669
  • 1
  • 18
  • 22
  • For me: var isLastChild = element === element.parentNode.lastChild results in: #text "\n ". What works for me (result equals true or false): var isLastChild = element === element.parentNode.lastElementChild and var isFirstChild = element === element.parentNode.firstElementChild – Rob Waa Jan 31 '22 at 20:37
1

Ask if there is a next element or not to know if it is the last or not:

if (typeof element.nextElementSibling == null) {
    //is last
    return;
} else {
    //is not last
}
IgniteCoders
  • 4,834
  • 3
  • 44
  • 62
1

you must use nextElementSibling, no nextSibling or typeof ...

function isLastElement(element) {
    return element.nextElementSibling === null;
}
DavidFM
  • 193
  • 7