Reputation: 557
I am dynamically creating a table of elements and storing them in an array. The following may seem like an absolute nightmare but this is how I have decided to sort it. My problem now comes to the addEventListener
where I want to add an onclick
event connected to PlayMusic()
. I have tried a simple .onclick =
and left out the function(){}
but then the PlayMusic()
gets executed immediately. Having the function(){}
in there, when I click on one of these elements the first param (i
) is the "last number used" (aka 22 out of 21 elements). How would I go about making sure each of these onclick
s has the correct index in their params?
var thetable = document.getElementById("mustable");
for(var i=0; i<fullists.length-1; i++)
{
fullists[i][2] = [];
fullists[i][3] = [];
for(var j=0; j<fullists[i][1].length; j++)
{
var row = thetable.insertRow();
fullists[i][2][j] = row.insertCell();
fullists[i][2][j].className = "musentry";
var header = fullists[i][0].substring(0,fullists[i][0].lastIndexOf("."));
if(fullists[i][1][j][1] != undefined)
var title = fullists[i][1][j][1];
else
var title = fullists[i][1][j][0].substring(fullists[i][1][j][0].lastIndexOf("/"));
fullists[i][2][j].innerHTML = header + "<br /><b>" + title + "</b>";
fullists[i][2][j].addEventListener("click",function() { PlayMusic(i,j); },false);
fullists[i][3][j] = 0;
}
}
Upvotes: 0
Views: 40
Reputation: 29092
The issue is that by the time the function executes, i
already has a different value because the loop already continued executing. If you change your loop to use let i
instead of var i
(same for j
) it will work, because let
in the for
iterator variable has a special behavior where it actually creates another copy of the variable scoped to the inside of the loop on every iteration, so that copy won't change.
Another way, which is basically the same thing but done explicitly: Store it inside another block-scoped variable first. E.g. const i2 = i
and then use i2
inside the function () {}
. Same for j
.
Alternatively, write .addEventListener(..., PlayMusic.bind(null, i, j))
. With bind
you can create a new function from a function, where a this
and arguments are already bound to it. Since the binding happens immediately and thereby captures the current values of i
and j
, that solves it too.
Upvotes: 1