Reputation: 183
I have this function that puts my objects where I want them to be, according to the array they are placed.
If they are in players[0] they go somewhere, if they are in players[1] they go eslsewhere. X and Y are just for ilustration purpose, they actualy are something like 600px for example, and all different.
This funstion also receives a flag by parameter, which tells the function if the src continues the same or if it is set to another src. Everything is working.
function putHands(flag){
if(flag == true) show= true;
else show = false;
for(var i = 0; i < 4; i++){
for(var j = 0; j < 13; j++){
if(i == 0){players[i][j].style.left = X; players[i][j].style.top = Y;}
if(i == 1){players[i][j].style.left = X; players[i][j].style.top = Y;}
if(i == 2){players[i][j].style.left = X; players[i][j].style.top = Y;}
if(i == 3){players[i][j].style.left = X; players[i][j].style.top = Y;}
if(show == true)
players[i][j].src = '../images/c'+players[i][j].id+'.gif';
}
}
}
Now I want to add what I said in the title, and I tried to do this:
players[i][j].addEventListener('mouseover', function() {players[i][j].src = '../images/c'+players[i][j].id+'.gif';});
I want to add each object an event onmouseover that changes itself src.
How can I achieve that using only simple JavaScript? What I tried returns the following error everytime I move mouse over the objects:
Uncaught TypeError: Cannot read property '13' of undefined
Upvotes: 0
Views: 1281
Reputation:
Just use this
to reference the bound element.
players[i][j].addEventListener('mouseover', function() {
this.src = '../images/c'+this.id+'.gif';
});
Otherwise you're using the i
and j
variables that are continuously overwritten in the loop, so that when the handler finally fires, it gets whatever value they were last assigned.
In other words, inside the handlers assigned, it would have been...
players[4][13]
...which is out of the range and obviously not the numbers you intended.
If you actually need i
and j
for any other purpose, you can either add them directly to the element itself (if that doesn't bother you), or you can create a new variable scope by invoking another function in every iteration of the loop, passing i
and j
to it, and creating the handler in that scope.
Also, because now your function really doesn't change per element, you can use a single function instead of creating multiple in a loop.
function handler() {
this.src = '../images/c'+this.id+'.gif';
}
function putHands(flag){
if(flag == true) show= true;
else show = false;
for(var i = 0; i < 4; i++){
for(var j = 0; j < 13; j++){
// ...your code...
players[i][j].addEventListener('mouseover', handler);
}
}
}
Now that one function is being efficiently reused for all the elements.
Also, a little off topic, but this...
if(flag == true) show= true;
else show = false;
can be shortened to this:
show = !!flag;
Technically it's a little different because the semantics of ==
isn't a simple truthy/falsey evaluation. If you actually need the behavior of ==
, then you can do:
show = flag == true;
Upvotes: 3