Prototype添加事件监听器

时间:2009-08-16 12:35:48

标签: javascript events loops prototypejs

出于某种原因,当我尝试将一个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的警报。我希望每个人都能提醒其各自的价值。我在这里做错了什么?

谢谢!

3 个答案:

答案 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);
        });     
    }
});