2017-05-09 4 views
3

Ich arbeite an einer sehr einfachen Anwendung. Wenn der Benutzer über ein Listenelement (li) schwebt, ändert sich die Textfarbe zu grün und wenn die Maus aus ist, wird es schwarz.Umfang einer anonymen Funktion als Argument

Warum können wir nicht lis[i] in der folgenden Code in der anonymen Funktion anstelle von this Schlüsselwort verwenden?

var lis = document.querySelectorAll('li'); 
var i = 0; 
for(; i < lis.length; i++){ 

    lis[i].addEventListener('mouseover', function(){ 

    this.style.color = 'green'; 

    }); 
    lis[i].addEventListener('mouseout', function(){ 

    this.style.color ="black"; 
    }); 
}; 

Antwort

2

Zum Zeitpunkt, zu dem die Funktion aufgerufen wird, ist die Schleife abgeschlossen. Es gibt nur eine i Variable und die Funktion sieht immer ihren aktuellen Wert. Also, wenn Sie i von innerhalb der Funktion verwenden, werden Sie es mit dem Wert lis.length sehen.

Es gibt Möglichkeiten, um es herum. Wenn Sie ES2015 verwenden können (möglicherweise durch eine Transpiler), dann können Sie schreiben:

const lis = document.querySelectorAll('li'); 
for(let i = 0; i < lis.length; i++){ 

    lis[i].addEventListener('mouseover',() => lis[i].style.color = 'green'); 
    lis[i].addEventListener('mouseout',() => lis[i].style.color ="black"); 
}; 

und jetzt haben Sie eine andere i für jedes Mal durch die Schleife.

Oder in älterem Code können Sie den Loop-Körper zu einer anderen Funktion ausdrücken und i als Parameter übergeben. Das hat die gleiche Wirkung, eine andere Variable für jede Ereignisbindung:

var lis = document.querySelectorAll('li'); 

var _loop = function _loop(i) { 

    lis[i].addEventListener('mouseover', function() { 
     return lis[i].style.color = 'green'; 
    }); 
    lis[i].addEventListener('mouseout', function() { 
     return lis[i].style.color = "black"; 
    }); 
}; 

for (var i = 0; i < lis.length; i++) { 
    _loop(i); 
} 

(das ist der Code automatisch durch babel vom ES2015 Beispiel hergestellt I oben gegeben haben)

3

Wenn die Callback-Funktion ausgeführt wird, Die Variable i hat aufgrund der Schleife den Wert lis.length, was dazu führt, dass der Wert lis[i]undefined ist. Verwenden Sie stattdessen die forEach-Funktion.

var lis = document.querySelectorAll('li'); 
 
lis.forEach(function (li) { 
 
    li.addEventListener('mouseover', function(){ 
 
    li.style.color = 'green'; 
 
    }); 
 
    li.addEventListener('mouseout', function(){ 
 
    li.style.color ="black"; 
 
    }); 
 
});
<ul> 
 
    <li>First LI</li> 
 
    <li>Second LI</li> 
 
</ul>

+0

Eigentlich zu bekommen, '' 'i''' noch definiert sein, aber auf dem letzten Wert der for-Schleife stecken (in diesem Fall lis.length, wodurch '' 'lis [i]' '' undefiniert). Dies ist auf Javascript-Schließungen zurückzuführen. Siehe @ Duncans Antwort. –

+1

@MichaelYang danke für den Hinweis, ich war mehr auf die Lösung als die Wurzel des Problems – Erazihel

+1

Natürlich - Ihre Lösung ist sehr gut! Ich wollte nur darauf hinweisen :-) –

-1

können Sie "e.srcElement" verwenden, um aktuelle Ziel wie dieses

let lis = document.querySelectorAll('li'); 
 

 
for (let i = 0; i < lis.length; i++) { 
 
    lis[i].addEventListener('mouseover', function(e){ 
 
    e.srcElement.style.color = 'green'; 
 
    }) 
 
    lis[i].addEventListener('mouseout', function(e){ 
 
    e.srcElement.style.color = 'black'; 
 
    }) 
 
}
<ul> 
 
    <li>First LI</li> 
 
    <li>Second LI</li> 
 
</ul>

+0

Sie können, aber das hat nichts mit der Frage zu tun, die sie gestellt haben – Quentin

Verwandte Themen