Spotlight jQuery replaceText

Alle zwei Wochen werfen wir einen sehr fokussierten Blick auf einen interessanten und nützlichen Effekt, Plug-In, Hack, Bibliothek oder sogar eine clevere Technologie. Wir werden dann versuchen, entweder den Code zu dekonstruieren oder ein kleines Projekt damit zu erstellen.

Heute schauen wir uns das exzellente replaceText jQuery Plugin an. Interessiert? Lass uns nach dem Sprung loslegen.


Ein Wort vom Autor

Als Webentwickler haben wir Zugriff auf eine erstaunliche Menge vorgefertigten Codes, sei es ein kleiner Ausschnitt oder ein vollwertiges Framework. Wenn Sie nicht etwas unglaublich Spezielles tun, besteht die Chance, dass Sie bereits etwas vorgefertigtes Element für Sie nutzen können. Leider sind viele dieser herausragenden Angebote anonym, besonders für Nicht-Hardcore-Fans.

Diese Serie versucht dieses Problem zu beheben, indem ein wirklich gut geschriebener, nützlicher Code eingeführt wird - sei es ein Plugin, ein Effekt oder eine Technologie für den Leser. Wenn er klein genug ist, werden wir versuchen, den Code zu dekonstruieren und zu verstehen, wie er Voodoo macht. Wenn es viel größer ist, versuchen wir, ein Mini-Projekt damit zu erstellen, um die Seile zu lernen und hoffentlich zu verstehen, wie man es in der realen Welt nutzt.


ReplaceText wird vorgestellt

Wir fangen an, indem wir uns auf das exzellente replaceText-Plugin von Ben Alman konzentrieren. Hier eine kurze Info:

  • Art: Plugin
  • Technologie: JavaScript [Auf der jQuery-Bibliothek aufgebaut]
  • Autor: Ben Alman
  • Funktion: Unaufdringliche, prägnante Möglichkeit, Textinhalte zu ersetzen

Das Problem

Das Ersetzen von Inhalten auf Ihrer Seite ist äußerst einfach. Immerhin die native JavaScript-Methode ersetzen scheint das gleiche zu tun. Wenn Sie sich besonders faul fühlen, ist es mit jQuery leicht, den gesamten Inhalt des Containers zu ersetzen.

 // Ersetzen Sie einfach $ ("# container"). Text (). Replace (/ text / g, 'ersatztext') // Ersetzen Sie den * gesamten * Inhalt des Containers var lazyFool = "gesamten Inhalt, wobei der Text extern ersetzt wird "; $ ("# container"). html (lazyFool);

Wie das Sprichwort sagt, nur weil Sie das können, heißt das nicht, dass Sie es tun sollten. Diese beiden Methoden werden im Allgemeinen gemieden [außerhalb von Randfällen], da sie bei dem, was sie tun, eine Reihe von Dingen brechen.

Das Hauptproblem bei diesen Ansätzen ist, dass sie die DOM-Struktur abflachen und jeden Nicht-Text-Knoten, den der Container enthält, effektiv vermasseln. Wenn Sie es schaffen, die HTML-Datei selbst zu ersetzen, verwenden Sie innerHTML oder jQuery's html, Sie haken noch jeden Event-Handler aus, der mit einem seiner untergeordneten Elemente verbunden ist, was einen vollständigen Deal-Breaker darstellt. Dies ist das Hauptproblem, das dieses Plugin zu lösen scheint.


Die Lösung

Der beste Weg, um mit der Situation und der Art und Weise, wie das Plugin damit umgeht, umzugehen, besteht darin, ausschließlich mit Textknoten zu arbeiten und diese zu ändern.

Textknoten erscheinen im DOM genauso wie reguläre Knoten, außer dass sie keine Kindknoten enthalten dürfen. Den Text, den sie enthalten, können Sie mit der nodeValue oder Daten Eigentum.

Durch die Arbeit mit Textknoten können wir die Komplexität des Prozesses erheblich verbessern. Wir müssen im Wesentlichen die Knoten durchlaufen, testen, ob es sich um einen Textknoten handelt, und falls ja, manipulieren Sie ihn auf intelligente Weise, um Probleme zu vermeiden.

Wir werden den Quellcode des Plugins selbst überprüfen, um zu verstehen, wie das Plugin dieses Konzept ausführlich implementiert.


Verwendungszweck

Wie die meisten gut geschriebenen jQuery-Plugins ist dies extrem einfach zu bedienen. Es verwendet die folgende Syntax:

$ (container) .replaceText (Text, Ersetzung);

Wenn Sie beispielsweise alle Vorkommen des Wortes 'val' durch 'value' ersetzen müssen, müssen Sie das Plugin wie folgt instanziieren:

 $ ("# container"). replaceText ("val", "value");

Ja, es ist wirklich so einfach. Das Plugin kümmert sich um alles für Sie.

Wenn Sie die Art von Amok mit regulären Ausdrücken sind, können Sie dies auch tun!

 $ ("# container"). replaceText (/ (val) / gi, "value");

Sie müssen sich keine Gedanken darüber machen, Inhalte in den Attributen eines Elements zu ersetzen. Das Plugin ist ziemlich clever.


Dekonstruieren der Quelle

Da das Plug-In aus nur 25 Zeilen Code besteht, ohne Kommentare und Ähnliches, führen wir einen kurzen Durchlauf durch die Quelle und erklären, welches Snippet was für welchen Zweck tut.

Hier ist die Quelle als Referenz. Wir werden jeden Abschnitt unten detailliert durchgehen.

 $ .fn.replaceText = function (suchen, ersetzen, text_only) return this.each (function () var node = this.firstChild, val, new_val, remove = []; if (node) do if (node.) .nodeType === 3) val = node.nodeValue; new_val = val.replace (Suchen, Ersetzen); if (new_val! == val) if (! text_only && / 

Richtig, lassen Sie uns den Code auf mäßig hoher Ebene durchlaufen.

 $ .fn.replaceText = function (suchen, ersetzen, text_only) ;

Schritt 1 - Der generische Wrapper für ein jQuery-Plugin. Der Autor hat zu Recht auf das Hinzufügen von vapid-Optionen verzichtet, da die bereitgestellte Funktionalität einfach genug ist, um eine davon zu rechtfertigen. Die Parameter sollten selbsterklärend sein -- nur Text wird später behandelt.

 return this.each (function () );

Schritt 2 - dies stellt sicher, dass sich das Plugin verhält, wenn das Plugin in einer Sammlung von Elementen übergeben wird.

 var node = this.firstChild, val, new_val, remove = [];

Schritt 3 - Erforderliche Deklaration der Variablen, die wir verwenden werden.

  • Knoten enthält das erste untergeordnete Element des Knotens.
  • val enthält den aktuellen Wert des Knotens.
  • new_val enthält den aktualisierten Wert des Knotens.
  • Löschen ist ein Array, das einen Knoten enthält, der aus dem DOM entfernt werden muss. Ich werde darauf in einigem Detail eingehen.
 if (Knoten) 

Schritt 4 - Wir prüfen, ob der Knoten tatsächlich existiert, d. H. Der übergebene Container hat untergeordnete Elemente. Erinnere dich daran Knoten enthält das erste untergeordnete Element des übergebenen Elements.

 do  while (node ​​= node.nextSibling);

Schritt 5 - Die Schleife durchläuft im Wesentlichen die Kindknoten und endet, wenn sich die Schleife am Endknoten befindet.

 if (node.nodeType === 3) 

Schritt 6 - Das ist der interessante Teil. Wir greifen auf die knotentyp property [schreibgeschützt] des Knotens, um die Art des Knotens abzuleiten. Ein Wert von 3 impliziert, dass es sich um einen Textknoten handelt, sodass wir fortfahren können. Wenn es Ihnen das Leben leichter macht, können Sie es so umschreiben: if (node.nodeType == Node.TEXT_NODE) ​​.

 val = node.nodeValue; new_val = val.replace (Suchen, Ersetzen);

Schritt 7 - Zuerst speichern wir den aktuellen Wert des Textknotens. Als Nächstes ersetzen wir Instanzen des Schlüsselworts schnell durch die Ersetzung durch das native ersetzen JavaScript-Methode. Die Ergebnisse werden in der Variablen gespeichert new_val.

 if (new_val! == val) 

Schritt 8 - Fahren Sie nur fort, wenn sich der Wert geändert hat!

 if (! text_only && / 

Schritt 9a - Erinnere dich an die nur Text Parameter. Das kommt hier ins Spiel. Hiermit wird festgelegt, ob der Container als solcher behandelt werden soll, der Elementknoten enthält. Der Code führt auch eine schnelle interne Überprüfung durch, um festzustellen, ob er HTML-Inhalt enthält. Dazu sucht er nach einem öffnenden Tag im Inhalt von new_val.

Wenn ja, wird ein Textknoten vor dem aktuellen Knoten eingefügt und der aktuelle Knoten wird dem hinzugefügt Löschen Array später bearbeitet werden.

 else node.nodeValue = neuer_wert; 

Schritt 9b - Wenn es sich nur um Text handelt, fügen Sie den neuen Text direkt in den Knoten ein, ohne durch das jonglierende DOM-Band zu gehen.

 remove.length && $ (remove) .remove ();

Schritt 10 - Sobald die Schleife abgeschlossen ist, entfernen wir schnell die angesammelten Knoten aus dem DOM. Der Grund, warum wir das tun, nachdem die Schleife abgeschlossen ist, ist, dass das Entfernen eines Knotens während des Laufs die Schleife selbst beschädigt.


Projekt

Das kleine Projekt, das wir heute bauen werden, ist ziemlich einfach. Hier ist die Liste unserer Anforderungen:

  • Hauptanforderung: Anwenden eines Hervorhebungseffekts auf aus Benutzereingaben extrahierten Text. Dies sollte vollständig vom Plugin übernommen werden.
  • Sekundäre Anforderung: Entfernen Sie die Markierung im laufenden Betrieb nach Bedarf. Wir werden ein winziges Codefragment zusammenfassen, um Ihnen dabei zu helfen. Nicht serienreif, sollte aber für unsere Zwecke recht gut sein.

Hinweis: Dies ist eher ein Proof of Concept als etwas, das Sie einfach unberührt einsetzen können. Um zu verhindern, dass der Artikel unkompliziert wird, habe ich offensichtlich eine Reihe von Abschnitten übersprungen, die für die Serienreife von Code von entscheidender Bedeutung sind, beispielsweise für die Validierung.

Der eigentliche Fokus sollte hier auf dem Plugin selbst und den darin enthaltenen Entwicklungstechniken liegen. Denken Sie daran, dies ist eher eine Beta-Demo, um etwas Cooles zu präsentieren, das mit diesem Plugin gemacht werden kann. Desinfizieren und validieren Sie Ihre Eingaben immer!


Die Basis: HTML und CSS

    Dekonstruktion: jQuery replaceText    

Dekonstruktion: jQuery replaceText

von Siddharth für die lieben Leute von Nettuts+

Diese Seite verwendet das beliebte replaceText-Plugin von Ben Alman. In dieser Demo markieren wir beliebige Textabschnitte auf dieser Seite. Füllen Sie das Wort aus, nach dem Sie suchen, und klicken Sie auf Los.

Anwenden von Hervorhebung

<-- Assorted text here -->

Das HTML sollte ziemlich erklärend sein. Alles, was ich getan habe, ist das Erstellen einer Texteingabe, zwei Links zum Anwenden und Entfernen der Hervorhebung sowie einen Absatz, der einen bestimmten Text enthält.

 body Schriftfamilie: "Myriad Pro", "Lucida Grande", "Verdana", serifenlos; Schriftgröße: 16px;  p Marge: 20px 0 40px 0;  h1 font-size: 36px; Polsterung: 0; Marge: 7px 0;  h2 font-size: 24px;  #container width: 900px; Rand links: auto; Rand rechts: auto; Auffüllen: 50px 0 0 0; Position: relativ;  #haiz padding: 20px; Hintergrund: #EFEFEF; -moz-border-radius: 15px; -webkit-border-radius: 15px; Grenze: 1px fest # C9C9C9;  #search width: 600px; Marge: 40px auto; Text ausrichten: Mitte;  #keyword width: 150px; Höhe: 30px; Polsterung: 0 10px; Grenze: 1px fest # C9C9C9; -moz-border-radius: 5px; -webkit-border-radius: 5px; Hintergrund: # F0F0F0; Schriftgröße: 18px;  # Anwenden-Hervorheben, # Entfernen-Hervorheben Auffüllen-Links: 40px;  .highlight Hintergrundfarbe: gelb; 

Wieder selbsterklärend und recht einfach. Das einzige, was zu beachten ist, ist die Klasse, die aufgerufen wird Markieren dass ich definiere. Dies wird auf den Text angewendet, den wir hervorheben müssen.

Zu diesem Zeitpunkt sollte Ihre Seite so aussehen:


Die Interaktion: JavaScript

Die erste Aufgabe des Tages besteht darin, unseren Link schnell mit seinen Handlern zu verknüpfen, damit der Text entsprechend hervorgehoben und nicht hervorgehoben wird.

 var searchInput = $ ("# Schlüsselwort"), searchTerm, searchRegex; $ ("# Apply-Highlight"). click (highLight); $ ("# remove-highlight"). bind ("click", function () $ ("# haiz"). removeHighlight (););

Sollte ziemlich einfach sein. Ich erkläre einige Variablen zur späteren Verwendung und füge die Verknüpfungen ihren Handlern hinzu. Markieren und removeHighlight sind extrem einfache Funktionen, die wir unten betrachten werden.

 Funktion highLight () searchTerm = searchInput.val (); searchRegex = new RegExp (searchTerm, 'g'); $ ("# haiz *"). replaceText (searchRegex, ''+ searchTerm +''); 
  • Ich habe mich für eine Vanille-Funktion entschieden und nicht für ein jQuery-Plugin, weil ich faul bin wie ein Steinhaufen. Wir beginnen mit der Erfassung des Wertes des Eingabefelds.
  • Als Nächstes erstellen wir ein reguläres Ausdrucksobjekt mit dem Suchbegriff.
  • Zum Schluss rufen wir die replaceText Plugin durch Übergabe der entsprechenden Werte. Ich entscheide mich direkt einzubeziehen Suchbegriff im Markup für die Kürze.
 jQuery.fn.removeHighlight = function () return this.find ("span.highlight"). each (function () mit (this.parentNode) replaceChild (this.firstChild, this););

Eine schnelle und schmutzige, hackige Methode, um die Arbeit zu erledigen. Und ja, dies ist ein jQuery-Plugin, da ich mich selbst einlösen wollte. Die Klasse ist immer noch hartcodiert.

Ich suche nur nach jeder Spanne mit einer Klasse von Markieren und Ersetzen des gesamten Knotens durch den darin enthaltenen Wert.

Bevor Sie Ihre Mistgabeln vorbereiten, denken Sie daran, dass dies nur zu Demonstrationszwecken ist. Für Ihre eigene Anwendung benötigen Sie eine sehr viel ausgefeiltere Methode zum Hervorheben von Lichtern.


Einpacken

Und wir sind fertig. Wir haben uns ein unglaublich nützliches Plugin angesehen, den Quellcode durchgegangen und schließlich ein Mini-Projekt damit erstellt.