1 Востаннє редагувалося FakiNyan (28.12.2013 16:51:40)

Тема: Проблема з лічильником в циклі

Здорів. От якщо написати такий код

 var elem = document.getElementsByClassName("first");
 console.log(elem.length);
 onload=function(){
     
     var height = elem[0].getElementsByTagName("li").length*37;
     console.log(0);
     elem[0].style.transition = ".5s 0 all ease";
     elem[0].addEventListener("mouseover",function(){elem[0].style.height = height+"px";});
     elem[0].addEventListener("mouseout", function(){elem[0].style.height = "42px";});

      var height = elem[1].getElementsByTagName("li").length*37;
     console.log(1);
     elem[1].style.transition = ".5s 0 all ease";
     elem[1].addEventListener("mouseover",function(){elem[1].style.height = height+"px";});
     elem[1].addEventListener("mouseout", function(){elem[1].style.height = "42px";});

      var height = elem[2].getElementsByTagName("li").length*37;
     console.log(2);
     elem[2].style.transition = ".5s 0 all ease";
     elem[2].addEventListener("mouseover",function(){elem[2].style.height = height+"px";});
     elem[2].addEventListener("mouseout", function(){elem[2].style.height = "42px";});
    
}

То все працює гарно. Але якщо от так це зробити

 var elem = document.getElementsByClassName("first");
 console.log(elem.length);
 onload=function(){
     for(var i=0; i<elem.length; i++)
     {
     var height = elem[i].getElementsByTagName("li").length*37;
     console.log(i);
     elem[i].style.transition = ".5s 0 all ease";
     elem[i].addEventListener("mouseover",function(){elem[i].style.height = height+"px";});
     elem[i].addEventListener("mouseout", function(){elem[i].style.height = "42px";});
    };
}

то вилазить купа глюків

Прихований текст

http://не-дійсний-домен/61iGC.png

Але якщо зробити

for(var i=0; i<elem.length-1; i++)

то помилок немає, але працює все зовсім не так, як треба.  Треба, щоб при наведені на відповідний <li> - змінювався саме він. А в мене якщо наводити на будь-який <li> - змінюється тільки останній по рахунку. Чому так???

2 Востаннє редагувалося Invader (28.12.2013 17:08:47)

Re: Проблема з лічильником в циклі

Чому тільки останній я не можу сказати з упевненістю, але писати треба отак:

elem[i].addEventListener("mouseover",function(){this.style.height = height+"px";});
elem[i].addEventListener("mouseout", function(){this.style.height = "42px";});

Ключове  слово this в IE здається або недоступне або доступне якось не так.

Подякували: FakiNyan1

3 Востаннє редагувалося FakiNyan (28.12.2013 17:16:19)

Re: Проблема з лічильником в циклі

Invader написав:

Чому тільки останній я не можу сказати з упевненістю, але писати треба отак:

elem[i].addEventListener("mouseover",function(){this.style.height = height+"px";});
elem[i].addEventListener("mouseout", function(){this.style.height = "42px";});

Ключове  слово this в IE здається або недоступне або доступне якось не так.

а чо не можна просто

elem[i]

замість this написати?
p.s. ну тепер все чотко! http://exmpl.bl.ee/

4 Востаннє редагувалося Invader (28.12.2013 17:28:16)

Re: Проблема з лічильником в циклі

this посилається на об’єкт-власник функції, тобто пишучи this.style.height виходить об’єктДоЯкогоПриєднанаФункціяОбробник.style.height. Всі функції посилаються на свої об’єкти.
А написавши отак:

elem[i].addEventListener("mouseout", function(){elem[i].style.height = "42px";});

атрибут висота буде змінюватися у останнього елементу (на момент зупинки циклу) з масиву елементів з класом first, хоча функцію додали до всіх елементів (виходить що всі функції посилаються на один і той же елемент в DOM).

Подякували: FakiNyan1

5

Re: Проблема з лічильником в циклі

Invader написав:

this посилається на об’єкт-власник функції, тобто пишучи this.style.height виходить об’єктДоЯкогоПриєднанаФункціяОбробник.style.height. Всі функції посилаються на свої об’єкти.
А написавши отак:

elem[i].addEventListener("mouseout", function(){elem[i].style.height = "42px";});

атрибут висота буде змінюватися у останнього елементу (на момент зупинки циклу) з масиву елементів з класом first, хоча функцію додали до всіх елементів (виходить що всі функції посилаються на один і той же елемент в DOM).

ну, щось починаю розуміти..

6

Re: Проблема з лічильником в циклі

FakiNyan написав:
     for(var i=0; i<elem.length; i++)
     {
     var height = elem[i].getElementsByTagName("li").length*37;
     console.log(i);
     elem[i].style.transition = ".5s 0 all ease";
     elem[i].addEventListener("mouseover",function(){elem[i].style.height = height+"px";});
     elem[i].addEventListener("mouseout", function(){elem[i].style.height = "42px";});
    };

В Javascript є замикання. В циклі змінна і міняється від 0 до elem.length. А оскільки в коді обробників

     elem[i].addEventListener("mouseover",function(){elem[i].style.height = height+"px";});
     elem[i].addEventListener("mouseout", function(){elem[i].style.height = "42px";})

ця змінна використовується, то вона нікуди не зникає після виконання коду, а "прив'язується" до функцій-обробників, причому прив'язується до всіх обробників одна і та ж змінна. Після виконання коду вона рівна elem.length -1 і тому у всіх callback'ах код 

 elem[i].style.height 

по факту стає таким:

 elem[elem.length-1].style.height 

і тому міняється тільки останній елемент.

Подякували: koala1