1

无法使以下代码正常工作。直接调用 swapLevel() 可以正常工作,但是 addEventListener() 似乎没有做任何事情?

JavaScript:

<script>
function load() {
    var arr = document.getElementById('menu').getElementsByClassName('level');

    for (var i=0; i<arr.length; i++) {
        arr[i].addEventListener('click', function(){swapLevel(i);}, false);
    }
    // automatically open the first level
    swapLevel(0);
}
document.addEventListener('DOMContentLoaded', load, false);
</script> 

HTML:

<div id="menu"> 
<a href="#" class="level">Level One</a> 
<span class="hidden" id="0">
<p>Some options here</p> 
</span> 
<a href="#" class="level">Level Two</a> 
<span class="hidden" id="1">
<p>More options</p> 
</span> 
<a href="#" class="level">Level Three</a> 
<span class="hidden" id="2">
<p>Even more options</p> 
</span> 
</div>
4

3 回答 3

1

您的索引不是您认为的那样,因为在for调用事件处理程序之前循环已经运行到完成,所以iarr.length所有事件处理程序中都是如此。相反,您需要这样的东西来捕获闭包中的索引值,这样它就是您希望它在每个事件处理程序中的样子。函数调用创建了一个闭包,所以这个例子使用了一个自执行匿名函数来创建闭包:

function load() {
    var arr = document.getElementById('menu').getElementsByClassName('level');

    for (var i=0; i<arr.length; i++) {
        (function(index) {
           arr[i].addEventListener('click', function(){swapLevel(index);}, false);
        })(i);
    }
    // automatically open the first level
    swapLevel(0);
}
于 2012-10-10T00:06:13.533 回答
0

每个处理程序都需要引用一个单独的值来传递给swapLevel. 要为此目的使用变量范围,您需要调用一个函数,并在该函数内构建您的处理程序。

function makeHandler(i) {
    return function(){swapLevel(i);}
}

for (var i=0; i<arr.length; i++) {
    arr[i].addEventListener('click', makeHandler(i), false);
}

另一种解决方案是简单地将属性直接放在元素上。

for (var i=0; i<arr.length; i++) {
    arr[i].__i__ = i
    arr[i].addEventListener('click', function(){swapLevel(this.__i__);}, false);
}

这种技术实际上也可以让您重用处理程序。

function handleSwap() {
   swapLevel(this.__i__);
}

for (var i=0; i<arr.length; i++) {
    arr[i].__i__ = i
    arr[i].addEventListener('click', handleSwap, false);
}
于 2012-10-10T00:05:59.117 回答
0

您需要在此处使用自评估闭包来捕获i循环每次迭代的值,否则您将获得iafter control has left the for loop:的值arr.length

var i;
for (i = 0; i < arr.length; ++i) {
    arr[i].addEventListener('click', function (i) {
        return function () { swapLevel(i); };
    }(i));
}
于 2012-10-10T00:09:44.177 回答