<button id="btn-0">Button 1!</button>
<button id="btn-1">Button 2!</button>
<button id="btn-2">Button 3!</button>



var prizes = ['A Unicorn!', 'A Hug!', 'Fresh Laundry!'];
for (var btnNum = 0; btnNum < prizes.length; btnNum++) {
  document.getElementById('btn-' + btnNum).onclick = function() {
    alert(prizes[btnNum]);
  }
}

Причина, по которой это не работает, заключается в том, что когда функция обращается к переменной за пределами своей области, она обращается к этой переменной, а не к замороженной копии, поэтому, когда пользователь нажимает кнопку, он всегда будет неопределенным, поскольку цикл for уже увеличен btnNum to 3. призы [3] не определены.

Мой вопрос: верно ли то же самое для document.getElementById ('btn-' + btnNum)? Цикл for присоединяет 3 обработчика событий к btn3? Или же он по-прежнему прикрепляет обработчик кликов к каждой кнопке, хотя все они будут оповещать о неопределенности.

Я задаю другой вопрос, а не просто пытаюсь заставить код работать.

-2
WinchenzoMagnifico 16 Дек 2015 в 07:18

3 ответа

Лучший ответ

Мой вопрос: верно ли то же самое для document.getElementById('btn-' + btnNum)?

Да. btnNum ссылается на одну и ту же переменную каждый раз (хотя она находится непосредственно в области видимости, а не в родительской области замыкания).

Цикл for присоединяет 3 обработчика событий к btn3?

Нет. document.getElementById(…) и btn вычисляются во время цикла, поэтому в настоящее время текущее значение btn действительно является ожидаемым - последнее назначение было инкремент, который изменяет значение между этими оценками тела цикла.

Или же он по-прежнему прикрепляет обработчик кликов к каждой кнопке, хотя все они будут оповещать о неопределенности.

Да. Предупреждение undefined происходит потому, что btn затем (посредством щелчка) оценивается в момент, когда оно несет значение 3.

2
Bergi 16 Дек 2015 в 04:49

Ну вот. ниже приведены мои ответы на ваши вопросы.

То же самое относится и к document.getElementById ('btn-' + btnNum).

Нет.

Цикл for присоединяет 3 обработчика событий к btn3?

Во время итерации btnNum доступен, поэтому он добавляет 3 прослушивателя событий для всех 3 кнопок.

Или же он по-прежнему прикрепляет обработчик кликов к каждой кнопке, хотя все они будут оповещать о неопределенности.

Да, к 3 кнопкам прикреплено 3 события. Он будет предупреждать неопределенное, потому что переменная prizes не существует и доступна глобально в window.prizes

var prizes = ['A Unicorn!', 'A Hug!', 'Fresh Laundry!'];
for (var btnNum = 0; btnNum < prizes.length; btnNum++) {
  document.getElementById('btn-' + btnNum).onclick = function() {
    alert(this.innerHTML);
    var no = this.getAttribute('id').split('-')[1];
    console.log(no);
    alert(window.prizes[no])
  }
}
<button id="btn-0">Button 1!</button>
<button id="btn-1">Button 2!</button>
<button id="btn-2">Button 3!</button>
-1
Venkat.R 16 Дек 2015 в 06:33

В этом случае Ссылка на btnNum уже выполнена, и поэтому вы получите 'Fresh Laundry!' во всех кликах. Причина того, что document.getElementById('btn-' + btnNum) работает так, как вы ожидаете, заключается в том, что event привязан в тот момент, когда выполняется loop, но функция callabck будет выполнена позже, когда пользователь нажмет ..

var prizes = ['A Unicorn!', 'A Hug!', 'Fresh Laundry!'];
for (var btnNum = 0; btnNum < prizes.length; btnNum++) {
  document.getElementById('btn-' + btnNum).onclick = (function(btnNum) {
    return function() {
      alert(prizes[btnNum]);
    }
  })(btnNum)
}
<button id="btn-0">Button 1!</button>
<button id="btn-1">Button 2!</button>
<button id="btn-2">Button 3!</button>
1
Rayon 16 Дек 2015 в 04:25