So verfolgen Sie Listen von Knoten in einem Jquery-Plugin (wenn Clients diese DOM-Knoten entfernen können)

8

Ich schreibe ein jQuery-Plugin, das auf eine bestimmte Anzahl von Knoten im DOM "zeigt". Wenn ich jedoch versuche, dass mein Plugin Referenzen auf eine Reihe von Knoten hält, mache ich mir Sorgen, dass sie "altbacken" werden.

(Obwohl ich feststelle, dass JavaScript Müll ist und nicht abstürzt, würde ich gerne meine Listen auf dem neuesten Stand halten und nicht an Dingen festhalten, die erfasst werden sollten.)

Das erste, was mir in den Sinn kam, war, dass es eine Art Haken geben könnte. Aber es scheint keinen Standard zu geben, der vertrauenswürdig aussieht:

Mit JQuery ist es möglich, eine Funktion ausführen zu lassen, wenn ein DOM-Element .remove () aufruft?

Rückruf beim Entfernen eines Elements aus dem DOM-Baum?

jQuery remove () Rückruf?

Das hat mich dazu gebracht, mich darüber Gedanken zu machen, Listen von Knoten zu pflegen, indem man ihnen ein Klassenattribut hinzufügt. Auf diese Weise würde ihre Mitgliedschaft in der Liste mit ihnen reisen. Aber wie man befürchten kann, kann dies pathologisch langsam aufzuzählen sein, und deshalb sollten Sie Ihre Anfrage als Tags vor den Klassen .

Zusätzlich zu möglichen Performance-Problemen frage ich mich, ob es für ein Plugin als schlechte Form gilt, Klassen für DOM-Knoten für diese Art von Zweck zu stochern, die nicht mit dem Styling zusammenhängt. (Eine der besseren Eigenschaften von .data() ist, dass es relativ bandextern ist, und mit Ausnahme dieses Listenproblems verwende ich das.)

Dies scheint ein weit verbreitetes Problem zu sein, das von anderen Plugins behoben wurde. Ich bin versucht, die Klassenlösung für ihre Korrektheit zu verwenden, obwohl sie langsamer ist. Aber gibt es einen schnelleren und kanonischeren Weg, der das Beste aus beiden Welten gibt?

    
HostileFork 22.11.2011, 00:16
quelle

2 Antworten

5

Ich würde darauf vertrauen, wie jQuery UI es tut. Speziell Droppables , pflegen sie intern eine Liste von jQuery-Objekten, die sie durchlaufen, wenn etwas darüber schwebt. Sie verwalten die Liste auf zwei Arten,

  1. Fügen Sie einen Destroy-Handler hinzu, der ausgelöst wird, wenn jQuery.remove () ausgeführt wird. (Sie hängen in jQuerys Funktionen entfernen, um dies zu tun) Dies wird nicht umgehen plain javascript obwohl obwohl,
  2. Überprüfen Sie einfach, ob es existiert, bevor Sie etwas tun.

Sie entfernen es nicht, nehme ich an, weil es möglich ist, es aus dem DOM zu entfernen und dann wieder einzufügen.

    
Andrew 25.11.2011, 16:45
quelle
1

Tut mir leid, dass ich Ihnen das antworte, aber "vertrauenswürdiger jQuery-basierter Code" ist ein Widerspruch in sich. FWIW:

jQuery erstellt, wie einige andere derzeit beliebte Scripting-Frameworks, ein Array -like-Objekt, das das Abfrageergebnis enthält, und kein Objekt, das NodeList Schnittstelle von W3C DOM Level 2+ Kern ( NodeList kurz). A NodeList ist live ; Array -ähnliche Objekte, bei denen es sich um native ECMAScript-Objekte und nicht um Host-Objekte handelt, sind (normalerweise) nicht vorhanden.

Wenn Sie solche Frameworks nicht verwenden, haben Sie dieses Problem nicht, wie bei allen (quasi-) standardmäßigen DOM-Methoden (wie getElementsByClassName() ) und Eigenschaften (wie document.forms ) return / yield a NodeList (manchmal sogar HTMLCollection ).

DOM-Level 2-Ereignisse Mutationsereignistypen , aber ab DOM Level 3-Events ( Working Draft ) Sie sind veraltet , und alle möglichen Hooks sind jetzt unzuverlässig und wahrscheinlich nicht einmal interoperabel .

Sie sollten also (quasi-) Standardmethoden dafür verwenden, nicht ein jQuery-Ergebnis und keine Mutationsereignisse.

Wenn Sie jedoch weiterhin den jQuery (-ish) -Weg verwenden möchten (mit all seinen anderen nicht offensichtlichen Mängeln), sollten Sie sich die Node -Eigenschaft von parentNode ansehen. Node s, die kein Document -Knoten sind, aber immer noch in einer Dokumentenstruktur sind, haben einen nicht null parentNode Eigenschaftswert (wobei null als Sprache der W3C DOM Level 2+ Kernspezifikation zu verstehen ist) -independent null , Sie sollten also nach allen Werten suchen, die in einer ECMAScript-Implementierung in true konvertiert werden. Dementsprechend haben alle anderen Node s einen parentNode Eigenschaftswert von null , also etwas, das in einer ECMAScript-Implementierung in false konvertiert wird.

Unter der Annahme, dass myNodes sich auf eine Array Instanz bezieht, deren Elemente Node s sind, und myNode sich auf ein solches Knotenobjekt bezieht, sollte Folgendes funktionieren:

%Vor%

Sie könnten dann gelegentlich über myNodes iterieren, z. B. in einer Funktion, die über window.setInterval() aufgerufen wird entferne die "veralteten" Knoten von ihm. Es ist sicherlich nicht so schön wie mit NodeList , aber es funktioniert auch, wenn Knoten entfernt werden, ohne jQuery zu verwenden, und selbst wenn Mutationsereignistypen nicht von der Laufzeitumgebung unterstützt werden.

Leider gibt jQuery() keinen Verweis auf eine Array -Instanz zurück. Also musst du zuerst einen machen, so:

%Vor%

(Wir verwenden hier die Tatsache, dass das Objekt, auf das sich jqObj bezieht, eine Eigenschaft length hat.)

Ich kann nicht sagen, was wäre ein guter Stil für ein jQuery-Plugin, denn aus Gründen, die jetzt offensichtlich sein sollten, versuche ich, jQuery überhaupt zu vermeiden.

Sie sollten auch lernen, die Programmiersprache * s * wie JavaScript zu unterscheiden und die (normalerweise sprachunabhängigen) APIs, die mit ihnen verwendet werden können, wie das DOM.

HTH.

    
PointedEars 02.12.2011 01:07
quelle