出于某种原因,当我尝试将一个actionlisetner分配给列表元素时,该值不会粘住。这就是我的意思:
Event.observe(window, 'load', function() {
for(i = 1; i <= $$('ul#review_list li').length; i++) {
$('cover_' + i).observe('click', function(event) {
alert(i);
});
}
});
因此#review_list中有7个列表元素,并且出于某种原因,无论何时点击任何li元素,我都会为每个单击的元素获得值为8的警报。我希望每个人都能提醒其各自的价值。我在这里做错了什么?
谢谢!
答案 0 :(得分:3)
试试这个:
Event.observe(window, 'load', function() {
for(i = 1; i <= $$('ul#review_list li').length; i++) {
(function (i) { // i is passed as an argument below
$('cover_' + i).observe('click', function(event) {
alert(i); // creates a closure around the argument i
});
})(i); // pass i as an argument
}
});
第一种方法不起作用的原因是alert(i)
;在循环变量i
周围创建一个闭包,它为每个事件赋值递增。在第一个事件被触发时,i
的值(对于所有事件来说都是常见的)为8,这就是无论你在哪里点击都能获得8的原因。
在第二种方法中,我发布的alert(i)
创建了一个围绕参数i
的闭包,它不会与任何其他事件监听器共享。
无论如何,您应该阅读this article on JavaScript closures以更好地理解它们。
答案 1 :(得分:2)
正如Ionut G. Stan所说,问题在于关闭“我”。 RaYell对你想要声明var是正确的(但不是那个解决问题的方法)。
该循环还会反复重新执行$$
调用,这不是很理想,并且完全不必要地调用$
来查找您已经查找过的元素(通过$$
})。
FWIW:
Event.observe(window, 'load', function() {
$$('ul#review_list li').each(function(elm, index) {
++index; // Now it's 1-based
elm.observe('click', function(event) {
alert(index);
});
});
});
$$
查找元素Enumerable#each
然后遍历调用给定函数的结果,并使用元素引用及其在数组中的从零开始的索引。然后,事件处理程序是对几个事物的闭包,包括传递给index
迭代器的#each
参数。
编辑:对不起,我刚才意识到我在下面做了一个大量的假设:事实上,cover_x元素是review_list下的列表项。如果他们不是,请忽略以下和我的道歉! - T.J。
这样可行,但它也不必要地复杂。事件委托可以是您的朋友:查找列表上的点击,而不是列出项目:
Event.observe(window, 'load', function() {
$('review_list').observe('click', function(event) {
var li;
li = event.findElement('li');
if (li) {
// ...your code here to interact with the list item.
// If you need the index, you can find it easily enough:
// index = parseInt(li.id.substring(6));
// ...since your IDs on the LI items is "cover_x" with x
// being the index.
}
});
});
答案 2 :(得分:-1)
尝试在for循环中添加var
关键字。如果没有var
,则分配一个全局变量i,然后在每次循环迭代时递增。因此,在循环之后,它将具有值8,并且您的alert
正在引用该值。
Event.observe(window, 'load', function() {
for(var i = 1; i <= $$('ul#review_list li').length; i++) {
$('cover_' + i).observe('click', function(event) {
alert(i);
});
}
});