Javascript关闭问题

时间:2011-07-04 08:24:09

标签: javascript closures

我知道这个问题有很多问题,但我仍然无法找到使这项工作正常工作的方法。

代码:

function doStuff () {
     for (var i = 0; i< elementsList.length; i++) {
        elementsList[i].previousSibling.lastChild.addEventListener("click", function(){
                   toggle(elementsList[i])}, false);


        }
    } // ends function


    function toggle (element) {
        alert (element);
    }

问题在于将变量传递给toggle函数。它与this关键字一起使用(但是它会发送对被点击项目的引用,在这种情况下是无用的),但不会与在Firefox中警告为未定义的elementsList [i]一起使用。

据我所知,使用匿名函数调用函数足以解决闭包问题,所以我错过了什么?

4 个答案:

答案 0 :(得分:3)

尝试:

function startOfFunction() {
    for (var i = 0; i< elementsList.length; i++) {
        elementsList[i].previousSibling.lastChild.addEventListener(
            "click",
            (function(el){return function(){toggle(el);};})(elementsList[i]),
            false
        );

    }
} // ends function


function toggle (element) {
    alert (element);
}

答案 1 :(得分:1)

问题是,你想使用var i! onClick事件中提供了i(自封闭和填充后)。由于你有一个循环,i被计算在内。现在,如果您点击任何元素,i将始终为elementsList.length(因为所有事件函数都访问相同的i)!

使用Matt的解决方案将起作用。

答案 2 :(得分:1)

作为解释:您在for循环中使用的匿名函数引用变量“i”以使元素切换。由于匿名函数使用变量的“实时”值,当有人点击元素时,“i”将始终为elementsList.length + 1.

Matt的代码示例通过将i粘贴到另一个“固定”的函数中来解决这个问题。这总是成立:

如果迭代连接事件的元素,不要使用简单的匿名函数,而是为每个元素创建一个新函数。 Matts答案的可读性更高的版本是:

function iterate () {
    for (var i = 0; i < list.length; i++) {
        // In here, i changes, so list[i] changes all the time, too. Pass it on!
        list[i].addEventListener(createEventFunction(list[i]);
    }
 }

 function createEventFunction (item) {
     // In here, item is fixed as it is passed as a function parameter.
     return function (event) {
         alert(item);
     };
 }

答案 3 :(得分:0)

尝试:

function doStuff () {
    for (var i = 0; i< elementsList.length; i++) {
        (function(x) {
            elementsList[x].previousSibling.lastChild.addEventListener("click", function(){
               toggle(elementsList[x])}, false);
        })(i);



    }
} // ends function

我认为传递elementsList[i]可能是一个问题,所以上面的代码有一个应该有用的闭包。