Я искал решение, позволяющее работать $.bind
и $.unbind
без проблем в динамически добавленных элементах.
Поскольку on () делает трюк для присоединения событий, чтобы создать фальшивую отвязку на тех, к которым я пришел:
const sendAction = function(e){ ... }
// bind the click
$('body').on('click', 'button.send', sendAction );
// unbind the click
$('body').on('click', 'button.send', function(){} );
Представляем себе для объяснения первого примера:
Области JavaScript являются функциональными, а не блочными, а создание замыкания означает, что охватывающая область добавляется в лексическую среду закрытой функции.
После того, как цикл завершается, переменная уровня функции i имеет значение 5, и это то, что внутренняя функция «видит».
blockquote>Во втором примере для каждого этапа итерации внешний литерал функции будет оценивать новый объект функции со своей собственной областью и локальной переменной
num
, значение которой установлено на текущее значениеi
, Посколькуnum
никогда не изменяется, он будет оставаться постоянным в течение срока действия замыкания. Следующий шаг итерации не перезаписывает старое значение, поскольку объекты функции являются независимыми.Имейте в виду, что этот подход является довольно неэффективным, поскольку для каждой ссылки необходимо создать два новых функциональных объекта. Это необязательно, поскольку их можно легко обменивать, если вы используете узел DOM для хранения информации:
function linkListener() { alert(this.i); } function addLinks () { for(var i = 0; i < 5; ++i) { var link = document.createElement('a'); link.appendChild(document.createTextNode('Link ' + i)); link.i = i; link.onclick = linkListener; document.body.appendChild(link); } }
Мне нравится писать простые объяснения для толстых людей, потому что я толстый, поэтому здесь идет ...
У нас есть 5 разделов на странице, каждый с идентификатором ... div1, div2, div3, div4, div5
jQuery может это сделать ...
for (var i=1; i<=5; i++) {
$("#div" + i).click ( function() { alert ($(this).index()) } )
}
Но действительно решая проблему (и медленно ее создавая) ...
for (var i=1; i<=5; i++) {
$("#div" + i).click (
// TODO: Write function to handle click event
)
}
for (var i=1; i<=5; i++) {
$("#div" + i).click (
function(num) {
// A functions variable values are set WHEN THE FUNCTION IS CALLED!
// PLEASE UNDERSTAND THIS AND YOU ARE HOME AND DRY (took me 2 years)!
// Now the click event is expecting a function as a handler so return it
return function() { alert (num) }
}(i) // We call the function here, passing in i
)
}
Если вы не можете опустить голову, тогда это должно быть легче понять и иметь тот же эффект ...
for (var i=1; i<=5; i++) {
function clickHandler(num) {
$("#div" + i).click (
function() { alert (num) }
)
}
clickHandler(i);
}
Это должно быть понятным, если вы помните, что значения переменных функций задаются при вызове функции (но это использует ту же мысль как и раньше)
clickHandler
за пределы цикла, только для стиля.
– Lee Kowalkowski
25 April 2012 в 16:32
В основном, в первом примере вы привязываете i
внутри обработчика onclick
непосредственно к i
вне обработчика onclick
. Поэтому, когда i
вне обработчика onclick
изменяется, i
внутри обработчика onclick
тоже изменяется.
Во втором примере вместо привязки к num
в onclick
, вы передаете его в функцию, которая затем привязывает его к num
в обработчике onclick
. Когда вы передаете его в функцию, значение i
будет скопировано , а не связано с num
. Поэтому, когда i
изменяется, num
остается неизменным. Копия происходит потому, что функции в JavaScript являются «замыканиями», что означает, что как только что-то передается в функцию, оно «закрыто» для внешней модификации.
Другие объяснили, что происходит, вот альтернативное решение.
function addLinks () {
for (var i = 0, link; i < 5; i++) {
link = document.createElement("a");
link.innerHTML = "Link " + i;
with ({ n: i }) {
link.onclick = function() {
alert(n);
};
}
document.body.appendChild(link);
}
}
В основном, бедные мужчины несут привязку.
В первом примере вы просто привязываете эту функцию к событию onclick:
function() {alert(i);};
Это означает, что в событии клика js должен предупредить значение функций i-переменной addlink. Его значение будет 5 из-за цикла for ().
Во втором примере вы создаете функцию, связанную с другой функцией:
function (num) {
return function () { alert(num); };
}
Это означает: если вызов со значением, верните мне функцию, которая будет предупреждать входное значение. Например. вызов function(3)
вернет function() { alert(3) };
.
Вы вызываете эту функцию со значением i на каждой итерации, поэтому вы создаете отдельные функции onclick для каждой ссылки.
Дело в том, что в первом примере ваша функция содержала ссылку на переменную, а во втором - с помощью внешней функции, которую вы заменили ссылкой фактическим значением. Это называется замыканием примерно потому, что вы «закрываете» текущее значение переменной внутри вашей функции, а не сохраняете ссылку на нее.
link.i = i;
) считается плохой практикой . – check_ca 16 February 2014 в 13:44data-something
). – Matthew Flaschen 15 March 2014 в 06:20link.i = i
наlink.setAttribute("data-link-index",i)
и заменитьalert(this.i)
наalert(Number(this.getAttribute("data-link-index")))
– check_ca 16 August 2017 в 14:44