Die Sache ist: Jeder kennt „Speicherlecks“. Es gibt mehrere gängige Szenarien:
Punkt 3 hat meine Aufmerksamkeit erregt. Ich weiß genau, was er bedeutet, zum Beispiel: „Angenommen, Sie entfernen manuell einen DOM-Knoten und der vom DOM-Knoten belegte Speicher sollte freigegeben werden, aber aufgrund von Nachlässigkeit enthält ein Teil des Codes immer noch einen Verweis auf den entfernten Knoten, was letztendlich dazu führt, dass der vom Knoten belegte Speicher nicht freigegeben wird.“ <div id="Wurzel"> <div class="child">Ich bin ein untergeordnetes Element</div> <button>Entfernen</button> </div> <Skript> let btn = document.querySelector('Schaltfläche') let Kind = Dokument.QuerySelector('.Kind') let root = document.querySelector('#root') btn.addEventListener('klicken', function() { root.removeChild(Kind) }) </Skript> Dieser Code entfernt den Knoten .child nach dem Klicken auf die Schaltfläche. Obwohl der Knoten nach dem Klicken tatsächlich aus dem DOM entfernt wird, weist die globale Variable child immer noch einen Verweis auf den Knoten auf, sodass der Speicher des Knotens nicht freigegeben werden kann. Lösung : Wir können den Verweis auf den .child-Knoten in die Rückruffunktion des Klickereignisses verschieben. Wenn dann der Knoten entfernt und die Rückruffunktion beendet wird, wird der Verweis auf den Knoten automatisch gelöscht, und es tritt natürlich kein Speicherverlust auf. (Dies ist tatsächlich eine Echtzeiterkennung, ob der Knoten im Ereignis vorhanden ist. Wenn er nicht vorhanden ist, löst der Browser die Ausführung der Entfernungsfunktion nicht aus.) <div id="Wurzel"> <div class="child">Ich bin ein untergeordnetes Element</div> <button>Entfernen</button> </div> <Skript> let btn = document.querySelector('Schaltfläche') btn.addEventListener('klicken', function() { let Kind = Dokument.QuerySelector('.Kind') let root = document.querySelector('#root') root.removeChild(Kind) }) </Skript> Ist dieser Code perfekt? NEIN. Weil es nach dem Auslösen jedes Ereignisses Verweise auf die untergeordneten und Stammknoten erstellt. Speicherverbrauch (Sie können sich vorstellen, dass einige Leute verrückt werden Tastenklicks…). Tatsächlich geht es auch anders: Wir ermitteln per Klick, ob im aktuellen Root-Knoten noch ein Child-Knoten vorhanden ist. Wenn ja, führen wir die Remove-Funktion aus, andernfalls tun wir nichts! Dies führt zu dem im Titel genannten Verhalten. Wie soll man urteilen? Traverse? Nein, das macht zu viel Mühe! Irgendwie fiel mir plötzlich der In-Operator in Lassen Sie uns die Szene zu diesem Zeitpunkt wiederherstellen: Öffnen Sie GitHub, suchen Sie nach dem Zufallsprinzip einen übergeordneten Knoten und rufen Sie ihn ab: Der rote Rahmen im Bild ist das übergeordnete Element, das wir erhalten möchten, und der orangefarbene Rahmen ist das untergeordnete Element, bei dem wir feststellen möchten, ob es vorhanden ist. let parent = document.querySelector('.position-relative'); let child = document.querySelector('.progress-pjax-loader'); Beachten Sie hier, dass wir einen DOM-Knoten (Array-ähnliches Objekt) erhalten und diesen vor der Operation verarbeiten müssen: let p_child=[...Eltern.Kinder]; Dann Konsole.log(Kind in p_child); ! ! ! Warum? (Zu diesem Zeitpunkt war dem Autor der Ernst der Lage noch nicht bewusst) Ich frage mich, ob etwas schiefgelaufen ist, also verwende ich zur Überprüfung die ES6-Includes-API: Konsole.log(p_child.includes(Kind)); Das stimmt! Lassen Sie es uns mit einem normalen Array überprüfen: ? ? ? An diesem Punkt fiel mir ein, MDN zu überprüfen: Dann habe ich Folgendes festgestellt: Wenn der In-Operator allein verwendet wird, erkennt er, ob der Wert, der dem Wert auf der linken Seite (als Index) entspricht, innerhalb des Objekts auf der rechten Seite (in den Eigenschaften und dem Prototyp) liegt ! Zurück zum obigen Code. Wir stellen Folgendes fest: Dies bestätigt unsere Schlussfolgerung. Offensichtlich ist „untergeordnetes Element“ nicht dasselbe wie „in der Prototypenkette vorhanden“ – dies führt zu einem weiteren Wissenspunkt: dem Unterschied zwischen Attribut und Eigenschaft! Nach einigen „Problemen“ sollte der Quellcode also direkt so lauten: <div id="Wurzel"> <div class="child">Ich bin ein untergeordnetes Element</div> <button>Entfernen</button> </div> <Skript> let btn = document.querySelector('Schaltfläche') let Kind = Dokument.QuerySelector('.Kind') let root = document.querySelector('#root') lass r_child = [...root.children] btn.addEventListener('klicken', function() { if(r_child.includes(child)){ // Oder Sie können einfach prüfen, ob das Kind null ist... root.removeChild(child) } }) </Skript> Ein etwas voreiliges Ende Deshalb kann Lesen und Lernen manchmal nicht „ohne den Versuch eines gründlichen Verständnisses“ geschehen. Sie müssen auch mutig genug sein, „herumzustöbern“ und lernen, wie man „Dokumente prüft“ [/lustiges Gesicht]. Zusammenfassen Dies ist das Ende dieses Artikels über den problematischen JS-Operator. Weitere Informationen zum problematischen JS-Operator finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, Sie werden 123WORDPRESS.COM auch in Zukunft unterstützen! Das könnte Sie auch interessieren:
|
<<: Detaillierte Schritte zum Konfigurieren der MySQL-Remoteverbindung unter Alibaba Cloud
>>: Sicherheitskonfiguration und Erkennung von SSL, nachdem die Website https aktiviert hat
Geschichtsroute Der Verlaufsmodus bezieht sich au...
Inhaltsverzeichnis 1. Übersicht über die logische...
Das Problem beim Zurücksetzen des Passworts für d...
1. Sehen Sie sich die Renderings an Weiterleiten ...
Inhaltsverzeichnis Einrichten einer einfachen HTT...
Vorwort MySQL bezeichnet die Schritte Vorbereiten...
Inhaltsverzeichnis Probleme, die Redux Toolkit lö...
Sie können sehen, dass ihre visuellen Effekte sehr...
Inhaltsverzeichnis 01 Einführung in YAML-Dateien ...
Inhaltsverzeichnis 1. Einleitung 2. Umweltvorbere...
Inhaltsverzeichnis 1. Docker installieren 2. Sona...
Inhaltsverzeichnis Vorwort Hauptimplementierungsc...
01 Winterflocken (nur einzeln) 02 Snowtop Caps (k...
Vorwort Bei der Projektfreigabe ist immer eine Ve...
1. Einleitung resolv.conf ist die Konfigurationsd...