Heim >Web-Frontend >js-Tutorial >JS-FAQ: Warum ist das i, das beim Klicken erscheint, immer das letzte?_Javascript-Tipps
Ich habe viele Leute gesehen, die diese Frage in der Front-End-Gruppe gestellt haben, und heute Abend hat jemand diese Frage erneut gestellt, also habe ich einen Artikel geschrieben, um das Problem zu klären. Schauen Sie sich zunächst den Code an. Nachdem Sie auf li geklickt haben, wird der Indexwert angezeigt, der dem aktuellen li entspricht. So viele Leute haben den folgenden Code geschrieben.
var aLi = document.getElementsByTagName('li'); for(var i = 0; i < aLi.length; i++){ aLi[i].onclick = function(){ alert(i); } }
Das Ergebnis ist jedoch nicht zufriedenstellend. Der Einfachheit halber sind wir uns einig, dass die Seite 2 li enthält. Nach dem Klicken auf li sind alle Popups 2.
Lassen Sie uns zunächst analysieren, warum das Ergebnis 1 ist. Wir können die Schleife einfach in zwei Teile teilen.
i = 0时,aLi[0].onclick = function(){alert(i)} i = 1时,aLi[1].onclick = function(){alert(i)} i = 2时,不满足条件跳出循环.
Beim Ausführen der Klickfunktion gibt es eine Bereichskette. Diese Bereichskette ist eine Liste von Objekten, die die Variablen im Codebereich definieren. (Wenn Sie mehr über den Inhalt des Variablenobjekts erfahren möchten, können Sie das Variablenobjekt anzeigen.) Wenn wir alarmieren (i), suchen wir von innen nach außen nach der Variablen i. Zu diesem Zeitpunkt befinden sich zwei Objekte in der Bereichskette dieser Funktion. Zu diesem Zeitpunkt ist die Schleife beendet und der Wert von i beträgt zu diesem Zeitpunkt 2. Wenn Sie also auf ein beliebiges li klicken, wird das Popup angezeigt 2, nicht der Indexwert, den wir wollen. Der Punkt ist, dass das, was auftaucht, Variable i, Variable i, Variable i ist. Sagen Sie wichtige Dinge dreimal.
Hier stellt sich also die Frage, wie wir dieses Problem lösen können. Was wir tun müssen, ist, den Wert von i jedes Mal im internen Bereich zu speichern, wenn wir ein Ereignis an aLi[i] binden. Die Lösung ist wie folgt.
var aLi = document.getElementsByTagName('li'); for (var i = 0; i < aLi.length; i++) { (function(i){ aLi[i].onclick = function () { alert(i); }; })(i) }
Dabei geht es um das Konzept des Bereichs auf Blockebene. Bevor ES6 herauskam, waren Funktionen das wichtigste Mittel zum Erstellen von Bereichen auf Blockebene. Hier platzieren wir eine Funktionsebene außerhalb von aLi[i].onclick, verwenden i als Parameter und analysieren die Ergebnisse erneut.
i = 0时, (function(i){ aLi[0].onclick = function(){ alert(i); } })(0) i = 1时, (function(i){ aLi[1].onclick = function(){ alert(i); } })(1) i = 2时,不满足条件跳出循环.
Aufgrund der zusätzlichen Ebene des selbstausführenden Funktionsumbruchs gibt es beim Klicken auf li drei Gültigkeitsebenen. Von innen nach außen sind dies: das variable Objekt innerhalb der Klickfunktion, das variable Objekt von die selbstausführende Funktion und der äußerste Bereich Das Fensterobjekt der Ebene. Bei der Suche nach der zweiten Ebene wurde festgestellt, dass i der selbstausführenden Funktion gleich dem übergebenen Parameterwert war, und der Wert von i zu diesem Zeitpunkt wurde entsprechend gespeichert, sodass der entsprechende Indexwert angezeigt wurde.
Lassen Sie mich ein häufiges js-Problem mit Ihnen teilen. Wenn Sie auf li klicken, werden der aktuelle Li-Index und die innerHTML-Funktion angezeigt
Wenn Sie auf eine davon klicken, wird die folgende Warnung angezeigt:
Nach unserem üblichen Denken sollte der Code so geschrieben sein:
var myul = document.getElementsByTagName("ul")[0]; var list = myul.getElementsByTagName("li"); function foo(){ for(var i = 0, len = list.length; i < len; i++){ list[i].onclick = function(){ alert(i + "----" + this.innerHTML); } } } foo();
Aber leider ist das Ergebnis so:
Warum ist der Index immer 4? Dies liegt am fehlenden Bereich auf Blockebene in js. Hier sind drei Lösungen
1. Verschlüsse verwenden
<script type="text/javascript"> var myul = document.getElementsByTagName("ul")[0]; var list = myul.getElementsByTagName("li"); function foo(){ for(var i = 0, len = list.length; i < len; i++){ var that = list[i]; list[i].onclick = (function(k){ var info = that.innerHTML; return function(){ alert(k + "----" + info); }; })(i); } } foo(); </script>
2. Verwenden Sie die neue Funktion let in ES6, um Variablen zu deklarieren
Mit let deklarierte Variablen haben einen Gültigkeitsbereich auf Blockebene, was offensichtlich die Anforderungen erfüllt. Es ist jedoch zu beachten, dass Sie „use strict“ (strikten Modus verwenden) hinzufügen müssen, damit es wirksam wird
<script type="text/javascript"> var myul = document.getElementsByTagName("ul")[0]; var list = myul.getElementsByTagName("li"); function foo(){'use strict' for(let i = 0, len = list.length; i < len; i++){ list[i].onclick = function(){ alert(i + "----" + this.innerHTML); } } } foo(); </script>
3. Führen Sie jquery ein und verwenden Sie „on“ oder „delegieren“ für die Ereignisbindung (sie haben alle die Eigenschaften eines Ereignis-Proxys)
<script type="text/javascript" src="jquery-1.8.2.min.js"></script> <script type="text/javascript"> $("ul").delegate("li", "click", function(){ var index = $(this).index(); var info = $(this).html(); alert(index + "----" + info); }); </script> <script type="text/javascript"> $("ul").on("click", "li", function(){ var index = $(this).index(); var info = $(this).html(); alert(index + "----" + info); }); </script>