Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Обработка события в теле цикла (https://javascript.ru/forum/events/46158-obrabotka-sobytiya-v-tele-cikla.html)

spaik 30.03.2014 23:53

Обработка события в теле цикла
 
Разметка содержит 3 элемента div класса 'div', js файл содержит следующий код:

var elements = document.getElementsByClassName('div');
for(var i=0;i<elements.length;i++){
elements[i].onclick=function (){
elements[i].style.background="red";
alert('blah-blah');
};
}

Я полагаю, что при клике на любом из элементов div должен изменяться этот элемент(на котором кликнули), но на деле изменяется только третий(причем при щелчке на любом из трёх). Здесь не могу понять логику совместной работы цикла и обработчика: ведь если стиль применяется лишь к третьему элементу(то-есть индекс elements'a внутри обработчика всегда устанавливается в последнюю позицию) то логично предположить, что обработчик должен устанавливаться лишь для третьего элемента(то есть индекс elements'a, на который вешается onclick, также будет устанавливаться в последнюю позицию),следовательно обработчик будет срабатывать только при клике на третьем элементе(на деле срабатывает на всех элементах). Объясните пожалуйста логику работы этого скрипта и в чём моя ошибка.

Vlasenko Fedor 31.03.2014 00:19

<div class="col">1</div>
<div class="col">2</div>
<div class="col">3</div>
<script>
  var elements = document.querySelectorAll('div.col'),
    len = elements.length,
    clickdiv = function () {
      this.style.background = "red";
      alert('blah-blah');
    };
  for (var i = 0; i < len; i++) {
    elements[i].onclick = clickdiv;
  }
</script>

spaik 31.03.2014 00:35

Хорошо, а как тогда быть если нужно, чтобы при клике по одному из описанных мной элементу менялся не сам этот элемент,а некий другой, соответствующий ему по индексу?

рони 31.03.2014 00:40

spaik,
http://javascript.ru/basic/closure#p...-ispolzovaniya

Vlasenko Fedor 31.03.2014 00:44

elements - это массив ваших дивов в примере, 1 индекс 0
console.log(elements);
чтобы обратится к нужному элементу
elements[0] - 1 элемент
elements[1] - 2 элемент
elements[2] - 3 элемент
elements[2].style.background = "red";

рони 31.03.2014 00:53

Цитата:

Сообщение от Poznakomlus
чтобы обратится к нужному элементу

--- это спам )))
Poznakomlus,
где индекс то взять в вашем коде его нет -- у вас this

Vlasenko Fedor 31.03.2014 01:09

рони,
Цитата:

Сообщение от рони
--- это спам )))

если я неправильно понял :)
понятно, что по ссылке пример лучше
но и такой имеет право на жизнь
<div class="col">1</div>
<div class="col">2</div>
<div class="col">3</div>
<div class="rez">Rezult 1</div>
<div class="rez">Rezult 2</div>
<div class="rez">Rezult 3</div>
<script>
  var elements = document.querySelectorAll('div.col'),
    result = document.querySelectorAll('div.rez'),
    len = elements.length,
    clickdiv = function () {
      result[this.innerHTML - 1].style.background = "red";
      alert('blah-blah');
    };
  for (var i = 0; i < len; i++) {
    elements[i].onclick = clickdiv;
  }
</script>

рони 31.03.2014 02:24

:write:
<!DOCTYPE HTML>

<html>

<head>
  <meta charset="utf-8">
  <title>Untitled</title>
</head>

<body>
<div class="col">1</div>
<div class="col">2</div>
<div class="col">3</div>
<div class="rez">Rezult 1</div>
<div class="rez">Rezult 2</div>
<div class="rez">Rezult 3</div>
<script>
  var elements = document.querySelectorAll('div.col'),
    result = document.querySelectorAll('div.rez'),
    len = elements.length,
    clickdiv = function (i) { return function () {
      result[i].style.background = "red";
      alert(i); }
    };
  for (var i = 0; i < len; i++) {
    elements[i].onclick = clickdiv(i);
  }
</script>

</body>
</html>

Vlasenko Fedor 31.03.2014 03:46

:write:
<div class="col">1</div>
<div class="col">2</div>
<div class="col">3</div>
<div class="rez">Rezult 1</div>
<div class="rez">Rezult 2</div>
<div class="rez">Rezult 3</div>
<script>
  var elements = document.querySelectorAll('div.col'),
    result = document.querySelectorAll('div.rez');
  [].forEach.call(elements, function (el, i) {
    el.onclick = function () {
      result[i].style.background = "red";
      alert(i);
    }
  });
</script>

spaik 31.03.2014 08:16

В моём примере сей глюк связан с областями видимости переменных.Проблема решается посредством замыкания.Спасибо за помощь

kostyanet 02.04.2014 14:17

Цитата:

Сообщение от spaik
но на деле изменяется только третий(причем при щелчке на любом из трёх). Здесь не могу понять логику совместной работы цикла и обработчика: ведь

В обработчик записывается ссылка которая меняется в каждой итерации и перестает меняться при выходе из цикла - эта последняя ссылка и используется в вашем обработчике, который повешан на все элементы участвовавшие в цикле.

Дело не видимости переменной, а в роде переменной.

Естественным образом решается через this.

При чем тут доступ по индексу я вообще не понял.

рони 02.04.2014 14:40

Цитата:

Сообщение от kostyanet
Естественным образом решается через this.

При чем тут доступ по индексу я вообще не понял

Цитата:

вы засоряите форум!!! повторяя уже сказанное на свой лад и совсем совсем не читая тему.
:-/

kostyanet 02.04.2014 14:49

Вы засоряете форум нелепыми выкриками. Автор написал что дело в видимости в самом конце, я счел своим долгом показать что не в видимости дело.

И мессагу свою отформатируйте.


Часовой пояс GMT +3, время: 18:16.