19.06.2017, 11:26
|
Аспирант
|
|
Регистрация: 18.06.2017
Сообщений: 87
|
|
Так а почему финальное? Ведь цикл выполняется последовательно, а это событие onclick лежит ВНУТРИ него!
Последний раз редактировалось Alessio18911, 19.06.2017 в 11:52.
|
|
19.06.2017, 12:00
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,129
|
|
Alessio18911,
одна переменная на все клики, почему переменная должна показывать, не то что есть на данный момент?нужно сохранить значение на момент создания функции, тогда нужно замыкание.
|
|
19.06.2017, 12:10
|
Аспирант
|
|
Регистрация: 18.06.2017
Сообщений: 87
|
|
Простите, возможно, Вам кажется очень простым этот вопрос, но для меня непонятно. Да, я понял, что на момент создания функции переменная должна показывать то, что в ней есть. Да, она одна на все клики, согласен. Но ведь onclick в цикле! Т.е. - возьмём мой ошибочный пример:
for (var i = 0; i < label.length; i++)
{
label[i].addEventListener('click', function() {
page.className = "page bg" + (i+1);
});
}
Получается, что - с учётом порядка действий при обработке кода - сначала выполнится цикл - т.е. i получит своё финальное значение. Затем будет выполняться функция add.EventListener и, соответственно, (i+1) получит сразу значение финального i + 1, т.е. 4. Так? Т.е. label[i], поскольку это массив, i будут присваиваться последовательно, по мере работы цикла, а функции - только последнее, т.к. это функция и она вложена в цикл?
|
|
19.06.2017, 12:25
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,129
|
|
Alessio18911,
возможно кто-то пояснит лучше ...
|
|
19.06.2017, 12:31
|
Аспирант
|
|
Регистрация: 18.06.2017
Сообщений: 87
|
|
Не обижайтесь, дело во мне.
|
|
19.06.2017, 13:12
|
Профессор
|
|
Регистрация: 27.11.2015
Сообщений: 2,899
|
|
Alessio18911,
Попробую объяснить.
Ваш пример
for (var i = 0; i < label.length; i++)
{
label[i].addEventListener('click', function() {
page.className = "page bg" + (i+1);
});
}
Здесь цикл по i - это создание обработчиков события click для всех элементов массива label.
строка
page.className = "page bg" + (i+1);
при этом не исполняется - просто запоминается в конкретном обработчике (причем запоминается идентификатор i, а не его значение).
По завершении цикла создания обработчиков i принимает финальное значение - и больше не меняется.
При исполнении по событию click обработчика для любого элемента из списка label выполнится вышеуказанная строка, в которой будет использоваться это значение
Иллюстрация:
Вариант с использованием значения i при создании обработчика
<div style="border:1px solid black">1</div>
<div style="border:1px solid black">2</div>
<div style="border:1px solid black">3</div>
<div style="border:1px solid black">4</div>
<script>
var divs = document.querySelectorAll('div');
for(var i = 0; i < divs.length; i++) {
divs[i].onclick = function(x)
{
return function()
{
alert(x)
}
}(i);
}
</script>
Вариант с использованием идентификатора i при создании обработчика
<div style="border:1px solid black">1</div>
<div style="border:1px solid black">2</div>
<div style="border:1px solid black">3</div>
<div style="border:1px solid black">4</div>
<script>
var divs = document.querySelectorAll('div');
for(var i = 0; i < divs.length; i++) {
divs[i].onclick = function()
{
alert(i)
};
}
</script>
Последний раз редактировалось Dilettante_Pro, 19.06.2017 в 13:57.
|
|
19.06.2017, 19:12
|
Аспирант
|
|
Регистрация: 18.06.2017
Сообщений: 87
|
|
Здравствуйте, Dilettante_Pro! Спасибо, что не прошли мимо. Перескажу, что я понял, своими словами.
Итак, в моём неправильном примере функция, которая вложена в addEventListener не может быть выполнена в процессе выполнения цикла, т.к. в коде нигде не прописан запуск её программным кодом, зато написано, что только человек - клацнув мышью - это сделает. Поэтому цикл выполняется и результат его работы - у каждого элемента массива привешен ОДИН И ТОТ же обработчик с выражением page.className = "page bg" + (i+1); При этом это выражение не высчитывалось, поскольку функция была "мёртвой". Цикл закончился, i дошло по финала, стало 2 (у меня 3 элемента в массиве) и "застыло навеки". Когда человек клацнул на какой-либо элемент массива, только это "оживило" функцию и она стала искать i, найдя его только ЗА своими пределами, т.е. у цикла, который, однако, уже отработал. Теперь, независимо от того, какой элемент массива будет кликнут, одно и то же i приведёт к вычислению одного и того же результата, поэтому чуда не произойдёт.
Берём правильный вариант. Для того, чтобы он был правильный, нужно заставить функцию работать при каждой итерации цикла. Для этого остаётся "оболочка" addEventListener, которая так и будет ждать клика от человека, а вот внутри неё - "живая" функция, которую принудительно будет оживлять вызов с (i) после её же закрытой фигурной скобки. В результате каждой итерации цикла выражение page.className = "page bg" + (i+1); будет высчитываться, и по окончании работы цикла у каждого элемента массива будет не просто обработчик с формулой, а "индивидуализированный" с готовым значением page.className. И клац мышью по любому элементу приведёт просто уже к присвоению соответствующего класса элементу.
Правильно понял?
Последний раз редактировалось Alessio18911, 19.06.2017 в 19:14.
|
|
19.06.2017, 19:19
|
Аспирант
|
|
Регистрация: 18.06.2017
Сообщений: 87
|
|
Добрый день, Rise! Только сегодня расплавившийся мозг вдруг выдал какую-то туманную идею, что, наверное, дело в том, как выполняется цикл с обработчиком. К обеду он приобрёл более-менее ясные очертания, а Ваше сообщение окончательно подтвердило мои раздумья. Возможно, я ещё не дошёл до тех глав учебника, где говорится про возможность НЕсинхронного выполнения цикла.. Но в самом начале - всё время идут примеры с последовательным выполнением строк за одну итерацию. И в главе про функции не говорится, что некоторые функции имеют такие особенности. Вот это незнание возможности асинхронности цикла и привело к загвоздке, которая разрешилась в результате совместных усилий. За что и благодарю и Вас, что уделили мне время.
|
|
19.06.2017, 19:33
|
Аспирант
|
|
Регистрация: 18.06.2017
Сообщений: 87
|
|
Rise, прошу прощения, КОД - знАчимое уточнение )
|
|
20.06.2017, 12:46
|
Профессор
|
|
Регистрация: 27.11.2015
Сообщений: 2,899
|
|
Alessio18911,
Сообщение от Alessio18911
|
Правильно понял?
|
Ок
|
|
|
|