removeChild - remove first or last node

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP

removeChild - remove first or last node



I have a jQuery one-liner which I'm trying to convert to vanilla JavaScript.


$('#nav ul li:' + (dir == -1 ? 'last' : 'first')).remove();



This works. But do I need 5 lines to replace a single line of jQuery ?


var li = document.querySelectorAll('#nav ul li');
var first = li[0];
var last = li[li.length- 1];
theParent = document.querySelector("#nav ul");
theParent.removeChild(dir == -1 ? last : first);





You could wrap those lines in a function and then it would be one line, but what would you gain?
– Heretic Monkey
Jul 29 at 17:22





can't you just use document.querySelector('#nav ul li:' + (dir == -1 ? 'last' : 'first')).remove()?
– Steve
Jul 29 at 17:22


document.querySelector('#nav ul li:' + (dir == -1 ? 'last' : 'first')).remove()





jQuery helps for a reason. That's essentially what jQuery is doing behind the scenes. Also @Steve .remove() does not work in IE.
– FrankerZ
Jul 29 at 17:23


.remove()





@Steve : We can't include :first and :last in querySelector. SyntaxError: '#nav ul li:first' is not a valid selector
– anjanesh
Jul 29 at 17:24






Thanks for the info; it does look like jQuery made a custom implementation for a reason. You might be able to use :first-child and :last-child, depending on your structure.
– Steve
Jul 29 at 17:35


:first-child


:last-child




2 Answers
2



The shortest way to write that in vanilla would be:


var nodes = document.querySelectorAll("#nav ul li"),
index = -1 == dir ? nodes.length-1 : 0;
nodes[index].parentElement.removeChild(nodes[index]);



...methinks. (obviously, nodes and index could be renamed to 1 letter var names and spaces could be removed, but that's not the point here).


nodes


index



By the way, as pointed out in the q comment, your version doesn't remove correct <li> when there are two or more <ul>s in #nav


<li>


<ul>


#nav



Testing:




// comment/uncomment this to test:
let dir = 1;

var nodes = document.querySelectorAll("#nav ul li"),
index = -1 == dir ? nodes.length-1 : 0;
nodes[index].parentElement.removeChild(nodes[index]);


<nav id="nav">
<ul>
<li>one</li>
<li>two</li>
<li>three</li>
</ul>
<ul>
<li>fourth</li>
<li>fifth</li>
<li><ul>
<li>sixth</li>
<li>seventh</li>
</ul></li>
</ul>
</nav>



Try this out



JS


// first or last
function remove(dir)
document
.querySelectorAll('#nav ul li:' + (dir < 0 ? 'last' : 'first') + '-child')
.forEach(function(element)
element.parentNode && element.parentNode.removeChild(element);
);


// by index
function removeByIndex(index)
document
.querySelectorAll('#nav ul li:nth-child(' + index + ')')
.forEach(function(element)
element.parentNode && element.parentNode.removeChild(element);
);



DEMO





Your version has same behavior with jQuery one liner only when there's only one <ul> in #nav. It will always remove the last <li> in the first <ul> instead of removing the last <li> in the last <ul>. Not to mention nested <ul>s.
– Andrei Gheorghiu
2 days ago



<ul>


#nav


<li>


<ul>


<li>


<ul>


<ul>





okay, now it handles everything
– dysfunc
2 days ago






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Comments

Popular posts from this blog

Executable numpy error

Trying to Print Gridster Items to PDF without overlapping contents

Mass disable jenkins jobs