Probleme beim Ausführen des folgenden Codes. Das Aufrufen von swapLevel () funktioniert direkt, aber der addEventListener () scheint nichts zu tun?

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>
0
mister martin 10 Okt. 2012 im 04:02

3 Antworten

Beste Antwort

Ihr Index ist nicht das, was Sie denken, weil die for - Schleife vollständig ausgeführt wurde, bevor der Ereignishandler aufgerufen wird, sodass i in allen Ihren Ereignishandlern arr.length ist. Stattdessen benötigen Sie so etwas, um den Indexwert in einem Abschluss zu erfassen, sodass er in jedem Ereignishandler so sein soll, wie Sie es möchten. Ein Funktionsaufruf erstellt einen Abschluss. In diesem Beispiel wird eine anonyme Funktion zur Selbstausführung verwendet, um den Abschluss zu erstellen:

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);
}
0
jfriend00 10 Okt. 2012 im 00:06

Sie müssen hier einen selbstauswertenden Abschluss verwenden, um den Wert von i bei jeder Iteration der Schleife zu erfassen, da Sie sonst den Wert von i erhalten, nachdem die Steuerung die for-Schleife verlassen hat: {{X2 }}.

var i;
for (i = 0; i < arr.length; ++i) {
    arr[i].addEventListener('click', function (i) {
        return function () { swapLevel(i); };
    }(i));
}
0
nathan 10 Okt. 2012 im 00:09

Jeder Handler muss auf einen separaten Wert verweisen, um an swapLevel übergeben zu werden. Um den variablen Bereich für diesen Zweck zu verwenden, müssen Sie eine Funktion aufrufen und Ihren Handler innerhalb dieser Funktion erstellen.

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

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

Eine andere Lösung besteht darin, einfach eine Eigenschaft direkt auf das Element zu setzen.

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

Mit dieser Technik können Sie den Handler auch wiederverwenden.

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

for (var i=0; i<arr.length; i++) {
    arr[i].__i__ = i
    arr[i].addEventListener('click', handleSwap, false);
}
0
I Hate Lazy 10 Okt. 2012 im 00:11