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イベントハンドラーが呼び出される前にループが完了し、すべてのイベントハンドラーでループが完了するiためarr.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

ここで自己評価クロージャを使用してi、ループの各反復での値をキャプチャする必要があります。そうしないと、i制御がforループを離れた後にの値を取得するためです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 に答える
0

各ハンドラーは、に渡すために個別の値を参照する必要がありますswapLevel。この目的で変数スコープを使用するには、関数を呼び出し、その関数内にハンドラーを作成する必要があります。

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

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

もう1つの解決策は、プロパティを要素に直接配置することです。

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 に答える