Jquery click Привязки не работают правильно при привязке нескольких копий
-
26-09-2019 - |
Вопрос
Кажется, я испытываю проблему при создании копий шаблона и правильно связывая метод .Click (). Возьмите следующий JavaScript, например:
function TestMethod() {
var test = Array();
test[0] = 0;
test[1] = 1;
test[2] = 2;
// Insert link into the page
$("#test_div").html("<a href=\"#\"></a><br>");
var list;
for (x = 0; x < test.length; x++) {
var temp = $("#test_div").clone();
temp.find('a').html("Item #" + test[x]);
temp.click(function () { alert(x); });
if (list == undefined)
list = temp;
else
list = list.append(temp.contents());
}
$("#test_div2").append(list);
}
Проблема, которую я вижу с этим, это то, что независимо от того, какой элемент пользователь нажимает, он всегда работает Alert (2), даже когда вы нажимаете на первые несколько предметов.
Как я могу заставить это работать?
Редактировать: Я сделал очень простой пример, который должен показать проблему гораздо яснее. Независимо от того, какой элемент вы нажимаете, он всегда показывает поле оповещения с номером 2 на нем.
Решение
Поправьте меня если я ошибаюсь, .valueOf()
В JS возвращает примитивное значение логического объекта .....
Это не произошло бы ShowObject(5,'T');
... ShowObject(objectVal.valueOf(), 'T');
Почему бы не использовать objects[x].Value
напрямую? ShowObject(objects[x].Value, 'T');
Woooossshhhh!
После поиска глубоко ... я нашел решение ...
Потому что это закрытие, это на самом деле не будет работать таким образом ...
Вот решение,
temp.find('a').bind('click', {testVal: x},function (e) {
alert(e.data.testVal);
return false;
});
Для лучшего объяснения, пожалуйста прочтите это... в средней части страницы, где она говорит Передача данных событий
Быстрая демонстрация вышеуказанного кода
Другие советы
Я думаю, что ваша проблема возникает из недоразумения областей в JavaScript. (Мои извинения, если я ошибаюсь.)
function () {
for (...) {
var foo = ...;
$('<div>').click(function () { alert(foo); }).appendTo(...);
}
}
В JavaScript, Только функции создают новый объем (обычно называют закрытие).
Итак, каждый раунд for
петля будет знать то же самое foo
, так как его объем function
, не for
. Отказ Это также относится к определенным событиям. К концу цикла, каждый click
узнаю то же самое foo
и знаю, что это последнее значение, которое оно было назначено.
Чтобы обойти это, либо создайте внутреннюю замыкание с немедленно выполненным, анонимным функцией:
function () {
for (...) {
(function (foo) {
$('<div>').click(function () { alert(foo); }).appendTo(...);
})(...);
}
}
Или, используя обратный вызов функции, такой как jQuery.each
:
function () {
$.each(..., function (i, foo) {
$('<div>').click(function () { alert(foo); }).appendTo(...);
});
}
Для вашей проблемы я бы пошел с последним (обратите внимание на изменения objects[x]
чтобы просто object
):
var list;
jQuery.each(data.objects, function (x, object) {
// Clone the object list item template
var item = $("#object_item_list_template").clone();
// Setup the click action and inner text for the link tag in the template
var objectVal = object.Value;
item.find('a').click(function () { ShowObject(objectVal.valueOf(), 'T'); }).html(object.Text);
// add the html to the list
if (list == undefined)
list = item;
else
list.append(item.contents());
});