What is the javascript equal $('#myUL li')

I want to write the whole file in pure java script, but this part:


$('#myUL li')

When I try:


document.querySelectorAll('#myUL li').addEventListener("click", function() {
   // code to be executed
});

The console.log report:


Uncaught TypeError: Object #<NodeList> has no method 'addEventListener'

Thank you

Hi ketting00,

As your error message suggests, document.querySelectorAll returns a NodeList and you cannot attach an event listener to a node list.
Instead, you will need to loop through the NodeList and attach the listener to the nodes it contains.

E.g.

var myLis = document.querySelectorAll('#myUL li');
for (var i=0, len = myLis.length; i<len; i++){
  myLis[i].addEventListener("click", function() {
    console.log("hi");
  });
}

HTH

Thanks. It works.

Hello, I’ve a question again.
How do I get ID from the li clicked. Here’s my experiment so far:


<ul id="myUL">
	<li>Song1</li>
	<li>Song2</li>
	<li>Song3</li>
	<li>Song4</li>
	<li>Song5</li>
</ul>

This is easy with jQuery:


tracks = [
	{"track":1,"name":"Song1","length":"00:55","file":"Song1"},
	{"track":2,"name":"Song2","length":"00:37","file":"Song2"},
	{"track":3,"name":"Song3","length":"01:05","file":"Song3"},
	{"track":4,"name":"Song4","length":"00:40","file":"Song4"},
	{"track":5,"name":"Song5","length":"00:59","file":"Song5"}
];

li = $('#myUL li').click(function() {
	var id = parseInt($(this).index());
	audio.src = path + tracks[id].file + extension;
	console.log(id);
});

I want it to be something like this:


for (var i=0, len = myLis.length; i<len; i++){
	myLis[i].addEventListener("click", function() {
		console.log(WHATEVER THAT GET ME THE ID);
		parseInt(myLis[i]); // This is not working
	});
}

Thank you

This is the ‘closure within a loop’ problem that seems to be quite common. The event handlers don’t get executed until after the loop has finished, so the value of i is not the same as it is when you add the event listener.

One solution to the problem is to do something like this:

for (var i=0, len = myLis.length; i<len; i++){
    (function(id){
        myLis[id].addEventListener("click", function() {
            audio.src = path + tracks[id].file + extension;
        });
    })(i);
}

What I’ve done here is to wrap the code which adds the listener in an anonymous function, which is immediately called and passed the current value of i (which the function receives as the argument index). This creates a closure which ‘traps’ the correct value of i.

Edit: Note that it’s not necessary to call parseInt on i, as it’s already an integer.

Thanks,
It works like a charm.
This is the first time ever I encounter something like this.

This make me realized that there are much more to learn about javascript. It’s amazing.