This question has already been answered:

I want using the next loop, put in the table a few <td> . However, for each <td> , you need to set the onmouseenter and onmouseleave properties .

 function getItems(){ var len = stickers.length; for(var i = 0; i < len; i++){ tbl = document.getElementById("itemsTable"); if(i==0||(i>4&&WIDTH>650)||i>2){ row = tbl.insertRow(-1); }else{ row = tbl.getElementsByTagName('tr'); row = row[row.length-1]; } cell = row.insertCell(-1); cell.className = "items"; cell.id = "item"+(i+1); c = document.getElementById("item"+(i+1)); c.style.backgroundImage = "url("+stickers[i][1]+")"; c.style.opacity = 0.0; //itemId = "item"+(i+1); //itemName = itemId+"description"; img = new Image(); img.onload = function () {outOfShadow("item"+(i+1), 1)}; img.src = stickers[i][1]; c.onmouseenter = function(){outOfShadow("item"+(i+1)+"description", 1)}; c.onmouseleave = function(){intoShadow("item"+(i+1)+"description", 0)}; } } 

Actually, nothing works .. I do not understand why (
If you uncomment the lines and replace them with "item"+(i+1) and "item"+(i+1)+"description" , you get half the working code, but all i + 1 objects are assigned equal to the length of the stickers array.
Can you please get the edited code that works correctly?
I do not quite understand where exactly the closures should be.

Reported as a duplicate by Grundy , cheops , user194374, PashaPash participants Jun 13 '16 at 11:55 .

A similar question was asked earlier and an answer has already been received. If the answers provided are not exhaustive, please ask a new question .

1 answer 1

In js, each function call creates an implicit scope object that refers to variables outside the function and also contains local variables of this function. But it does not work because event handlers on mouseenter and mouseleave get the value of i from the same scope in which by the end of the loop the value of the variable i becomes equal to len .

You need each handler to refer to its i th scope. that is, so:

 function getItems() { var len = stickers.length; for(var i = 0; i < len; i++) { c.onmouseenter = function(x) { return function() { outOfShadow("item"+(x)+"description", 1); } }(i+1); // i ый scope ссылается на текущее значение i в цикле. c.onmouseleave = function(x) { return function() { intoShadow("item"+(x)+"description", 0); }; }(i+1); // тоже самое и здесь } } 
  • more thanks, now I figured it out! - Sasha