2014-10-07 2 views
0
<button>test</button> 
<button>test</button> 
<button>test</button> 
<button>test</button> 
<button>test</button> 
<script> 
var nodes = document.getElementsByTagName('button'); 
function clicked(i){ 
    console.log('pass'); 

    // Closure 
    // return function(){ 
    // console.log(i); 
    // } 

} 
for (var i = 0; i < nodes.length; i++) { 
    nodes[i].addEventListener('click', clicked(i)); 
} 
</script> 

Я стараюсь иметь полное понимание о закрытии js, вышеприведенная функция добавляет даже слушателя к кнопкам. он консольный журнал «pass» 5 раз, а затем ничего не делает при нажатии кнопки. но если я раскомментирую бит закрытия (возврат), console.log выдает эхо из i, но не регистрирует 'pass'. Я нашел ответ, но я не понимаю, почему с закрытием onclick не записывает строку «» «строка при нажатии кнопки вместо этого выходит из i.Закрытие JavaScript в eventlistener

How do JavaScript closures work?

ответ

2

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

Я не понимаю, почему с закрытием onclick не записывает строку «pass» при нажатии кнопки, а выходит из i.

хорошо, ваше закрытие было

return function(){ 
    console.log(i); 
} 

Почему бы, что лог ничего, кроме i?

Функция, которая создает это закрытие, должна регистрироваться пять раз во время инициализации страницы (как вы вызываете пять раз в цикле, каждый раз, когда он регистрирует строку и возвращает закрытие).

Вы можете использовать bind.

nodes[i].addEventListener('click', clicked.bind(nodes[i], i)); 

Это даст вам i в качестве параметра функции, так что вы можете сделать

console.log("pass", i); 
+0

Этот ответ является потрясающим ... Вы в последний раз редактируете вещи, даже четко. Big ty – Bruce

+0

на самом деле это тоже работает узлы [i] .addEventListener ('click', clicked.bind (узлы, i)); – Bruce

+0

Да. Вы можете установить этот первый параметр так, как хотите. Он определяет, что 'this' будет внутри вашего обработчика событий (но вы этого не используете). Вы можете протестировать его с помощью 'console.info (this)'. Привязать его к элементу, который был нажат ('nodes [i]'), может пригодиться, если вы хотите обратиться к этому узлу DOM (чтение атрибутов или что-то в этом роде). – Thilo

0

Попытка ответить на исходный вопрос, как просили ...

, но я не получается, почему с закрытием onclick не записывает строку «pass» , когда нажата кнопка, а выходит из системы i

Вернуться к коду без закомментированного секции ...

<button>test</button> 
<button>test</button> 
<button>test</button> 
<button>test</button> 
<button>test</button> 
<script> 
    var nodes = document.getElementsByTagName('button'); 
    function clicked(i) { 
     console.log('pass'); 

     //Closure 
     return function(){ 
      output(i); 
     } 

    } 
    function output(i) { 
     alert('The value of the closure i for this button is: '+i); 
    } 
    for (var i = 0; i < nodes.length; i++) { 
     nodes[i].addEventListener('click', clicked(i)); 
    } 
</script> 
<style> 
    html { 
     counter-reset: button-count -1; 
    } 

    button:after { 
     content: ' ' counter(button-count); 
     counter-increment: button-count; 
    } 
</style> 

(Я также добавил немного больше, чтобы помочь объяснить)

При инициализации обработчиков событий в for loop, вам передают возвращаемое значение из clicked(i) в качестве указателя функции, который будет вызываться при нажатии на node[i]. В исходном коде, возвращаемое значение является ссылкой на анонимной функции определяется как:

function(){ 
    console.log(i); 
} 

Так это то, что выполняется при нажатии кнопки я - не clicked. clicked выполнен только в течение for loop. Вы увидите проход для каждой кнопки в консоли в течение for loop.

лексическая область для анонимной функции включает в себя объем его функция clicked, содержащим поэтому параметр i является в рамках для анонимной функции. Каждый раз, когда clicked заканчивается, в течение for loop, отдельный закрытие создано по параметру i, сохраняя его значение для этого конкретного вызова.

В приведенном выше коде, я создал функцию под названием вывод, который принимает параметр I, поэтому этот

function(){ 
    output(i); 
} 

... вызывается при нажатии кнопки я: также имеющий замыкание на i.

Я также добавил некоторые стили CSS, чтобы набрать кнопки.

Смежные вопросы