JS: remove lastChild only works every second button click

danielr1996 picture danielr1996 · May 15, 2015 · Viewed 7.8k times · Source

I use this code to delete the last item of an <ul> list, but only on the second, fourth, sixth, ... every second click on the button the item gets removed, but every click the message appears. What can I do that the element gets deleted on every click.

Answer

scniro picture scniro · May 15, 2015

This is because .lastChild returns all nodes, including empty text nodes which exist in your <ul>. Use .lastElementChild instead to target your <li> nodes

The difference between this property and lastElementChild, is that lastChild returns the last child node as an element node, a text node or a comment node (depending on which one's last), while lastElementChild returns the last child node as an element node (ignores text and comment nodes).

See HTML DOM lastChild Property and HTML DOM lastElementChild Property for more information

document.getElementsByTagName('input')[0].onclick = function () {
    var list = document.getElementById('list'), item = list.lastElementChild;
    list.removeChild(item);
};
<ul id="list">
    <li>List item 1</li>
    <li>List item 2</li>
    <li>List item 3</li>
    <li id="child">List item 4</li>
    <li>List item 5</li>
</ul>
<input type="button" value="Delete last">

Some more details on why this is happening... When you format your markup with clean spacing, what I think of as "phantom" text nodes silently exist within your <ul>. If you minify this markup to the following, your first example would indeed work fine

<ul id="list"><li>List item 1</li><li>List item 2</li><li>List item 3</li><li id="child">List item 4</li><li>List item 5</li></ul>

Plunker Link - minifed markup example using .lastChild