Spotlight jQuery replaceText

A settimane alterne, daremo un'occhiata ultra focalizzata a un effetto interessante, plug-in, hack, libreria o anche una tecnologia elegante. Quindi tenteremo di decostruire il codice o creare un piccolo progetto divertente con esso.

Oggi daremo un'occhiata all'eccellente plugin jQuery replaceText. Interessato? Iniziamo dopo il salto.


Una parola dall'autore

Come sviluppatori web, abbiamo accesso a una quantità impressionante di codice precostruito, che si tratti di un piccolo frammento o di un quadro completo. A meno che tu non stia facendo qualcosa di incredibilmente specifico, è probabile che ci sia già qualcosa di precompilato da sfruttare. Sfortunatamente, molte di queste offerte stellari languiscono nell'anonimato, specialmente per la folla non-hardcore.

Questa serie cerca di correggere questo problema introducendo del codice veramente ben scritto, utile - sia esso un plugin, un effetto o una tecnologia per il lettore. Inoltre, se è abbastanza piccolo, tenteremo di decostruire il codice e capire come lo fa voodoo. Se è molto più grande, cercheremo di creare un mini progetto con esso per imparare le corde e, si spera, capire come utilizzarlo nel mondo reale.


Presentazione di replaceText

Stiamo dando il via alle cose concentrandoci sull'eccellente plugin replaceText di Ben Alman. Ecco alcune informazioni rapide:

  • Genere: Collegare
  • Tecnologia: JavaScript [Costruito sulla libreria jQuery]
  • Autore: Ben Alman
  • Funzione: Modo discreto e conciso per sostituire il contenuto testuale

Il problema

Sostituire il contenuto della pagina è estremamente semplice. Dopo tutto, il metodo JavaScript nativo sostituire sembra fare la stessa cosa Se ti senti particolarmente pigro, jQuery rende l'intero contenuto del contenitore estremamente osceno.

 // Usando solo sostituire $ ("# contenitore"). Text (). Replace (/ text / g, 'replacement text') // Sostituzione del * intero * contenuto del contenitore var lazyFool = "intero contenuto con testo sostituito esternamente "; . $ ( "# Contenitore") html (lazyFool);

Come dice il proverbio, solo perché puoi farlo non significa davvero che dovresti farlo. Entrambi questi metodi sono generalmente evitati [al di fuori dei casi limite] perché rompono un sacco di cose mentre fanno quello che fanno.

Il problema principale di questi approcci è che essi appiattiscono la struttura DOM in modo efficace avvitando ogni nodo non testuale del contenitore. Se riesci a sostituire lo stesso html, usando innerHTML o di jQuery html, continuerai a sganciare ogni gestore di eventi collegato a uno qualsiasi dei suoi figli, che è un vero e proprio rompicapo. Questo è il problema principale che questo plugin sembra risolvere.


La soluzione

Il modo migliore per gestire la situazione e il modo in cui il plugin lo gestisce è di lavorare e modificare esclusivamente i nodi di testo.

I nodi di testo appaiono nel DOM proprio come i nodi regolari, tranne per il fatto che non possono contenere childnodes. Il testo che contengono può essere ottenuto usando il nodeValue o dati proprietà.

Lavorando con i nodi di testo, possiamo rendere molte delle complessità coinvolte nel processo. Avremo essenzialmente bisogno di scorrere i nodi, testare se si tratta di un nodo di testo e se sì, procedere a manipolarlo in modo intelligente per evitare problemi.

Esamineremo il codice sorgente del plugin stesso in modo da poter capire come il plugin implementa questo concetto in dettaglio.


uso

Come i plugin jQuery più ben scritti, questo è estremamente facile da usare. Usa la seguente sintassi:

$ (container) .replaceText (testo, sostituzione);

Ad esempio, se devi sostituire tutte le occorrenze della parola 'val' con 'valore', ad esempio, devi istanziare il plugin in questo modo:

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

Sì, è davvero così semplice. Il plugin si prende cura di tutto per te.

Se sei il tipo che si nutre di espressioni regolari, puoi farlo anche tu!

 $ ("# contenitore"). replaceText (/ (val) / gi, "valore");

Non devi preoccuparti di sostituire il contenuto negli attributi di un elemento, il plugin è abbastanza intelligente.


Decostruire la fonte

Poiché il plug-in è composto da sole 25 righe di codice, quando viene rimosso dai commenti e così via, eseguiremo una rapida analisi della fonte per spiegare quale frammento fa cosa e per quale scopo.

Ecco la fonte, per riferimento. Di seguito esamineremo ciascuna parte in dettaglio.

 $ .fn.replaceText = function (search, replace, text_only) return this.each (function () var node = this.firstChild, val, new_val, remove = []; if (nodo) do if (nodo .nodeType === 3) val = node.nodeValue; new_val = val.replace (cerca, sostituisci); if (new_val! == val) if (! text_only && / 

Esatto, eseguiamo un livello moderatamente completo del codice.

 $ .fn.replaceText = function (search, replace, text_only) ;

Passo 1 - Il wrapper generico per un plugin jQuery. L'autore, giustamente, si è astenuto dall'aggiungere opzioni vapid poiché la funzionalità fornita è abbastanza semplice da giustificarne una. I parametri dovrebbero essere auto esplicativi -- solo testo sarà gestito un po 'più tardi.

 ritorna this.each (function () );

Passo 2 - this.each si assicura che il plugin si comporti quando il plugin viene passato in una raccolta di elementi.

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

Passaggio 3 - Requisito di dichiarazione delle variabili che useremo.

  • nodo contiene il primo elemento figlio del nodo.
  • val mantiene il valore corrente del nodo.
  • new_val detiene il valore aggiornato del nodo.
  • rimuovere è una matrice che conterrà il nodo che dovrà essere rimosso dal DOM. Entrerò nei dettagli su questo tra un po '.
 if (nodo) 

Passaggio 4 - Controlliamo se il nodo esiste realmente, ovvero il contenitore che è stato passato ha elementi figlio. Ricordatelo nodo contiene il primo elemento figlio dell'elemento passato.

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

Passaggio 5 - Il ciclo essenzialmente, bene, scorre attraverso i nodi figli terminando quando il ciclo si trova sul nodo finale.

 if (node.nodeType === 3) 

Passaggio 6 - Questa è la parte interessante. Accediamo al nodeType proprietà [sola lettura] del nodo per dedurre che tipo di nodo è. Un valore di 3 implica che è un nodo di testo, quindi possiamo procedere. Se ti rende la vita più facile, puoi riscriverla in questo modo: if (node.nodeType == Node.TEXT_NODE) ​​.

 val = node.nodeValue; new_val = val.replace (cerca, sostituisci);

Passaggio 7 - Memorizziamo il valore corrente del nodo di testo, in primo luogo. Successivamente, sostituiremo rapidamente le istanze della parola chiave con la sostituzione con il nativo sostituire Metodo JavaScript I risultati vengono memorizzati nella variabile new_val.

 if (new_val! == val) 

Passaggio 8 - Procedere solo se il valore è cambiato!

 se (! text_only && / 

Passaggio 9a - Ricorda il solo testo parametro. Questo entra in gioco qui. Questo è usato per specificare se il contenitore deve essere trattato come uno che contiene nodi di elementi all'interno. Il codice esegue anche un rapido controllo interno per vedere se contiene contenuto HTML. Lo fa cercando un tag di apertura nei contenuti di new_val.

Se sì, un textnode viene inserito prima del nodo corrente e il nodo corrente viene aggiunto al rimuovere array da gestire in seguito.

 else node.nodeValue = new_val; 

Passaggio 9b - Se si tratta solo di testo, inserisci direttamente il nuovo testo nel nodo senza passare attraverso il gioco di giocoleria DOM.

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

Passaggio 10 - Alla fine, una volta terminato il ciclo, rimuoveremo rapidamente i nodi accumulati dal DOM. Il motivo per cui lo stiamo facendo dopo che il ciclo ha finito di funzionare è che la rimozione di un nodo a metà corsa rovinerà il loop stesso.


Progetto

Il piccolo progetto che costruiremo oggi è abbastanza semplice. Ecco la lista dei nostri requisiti:

  • Requisito primario: Applicazione di un effetto di evidenziazione al testo che viene estratto dall'input dell'utente. Questo dovrebbe essere curato completamente dal plugin.
  • Requisito secondario: Rimozione dell'evidenziatore al volo, come richiesto. Ci sarà un piccolo frammento di codice per aiutare con questo. Non è pronto per la produzione, ma dovrebbe fare abbastanza bene per i nostri scopi.

Nota: Questa è più una prova di concetto che qualcosa che puoi semplicemente schierare intatta. Ovviamente, nell'interesse di impedire che l'articolo diventi poco soddisfacente, ho saltato alcune sezioni che sono della massima importanza per la codifica pronta per la produzione, ad esempio per la convalida.

L'attenzione reale qui dovrebbe essere sul plugin stesso e sulle tecniche di sviluppo che contiene. Ricorda, questa è più di una demo beta per mostrare qualcosa di interessante che può essere fatto con questo plugin. Disinfetta e convalida sempre i tuoi input!


La Fondazione: HTML e CSS

    Decostruzione: jQuery replaceText    

Decostruzione: jQuery replaceText

da Siddharth per le persone adorabili a Nettuts+

Questa pagina utilizza il popolare plugin replaceText di Ben Alman. In questa demo, la stiamo usando per evidenziare blocchi di testo arbitrari su questa pagina. Compila la parola, stai cercando e vai avanti.

Applica evidenziare Sposta evidenzia

<-- Assorted text here -->

L'HTML dovrebbe essere piuttosto esplicativo. Tutto ciò che ho fatto è creare un input di testo, due link da applicare e rimuovere l'evidenziazione, nonché un paragrafo contenente un testo assortito.

 body font-family: "Myriad Pro", "Lucida Grande", "Verdana", sans-serif; font-size: 16px;  p margin: 20px 0 40px 0;  h1 font-size: 36px; padding: 0; margine: 7px 0;  h2 font-size: 24px;  #container width: 900px; margin-left: auto; margin-right: auto; imbottitura: 50px 0 0 0; posizione: relativa;  #haiz padding: 20px; background: #EFEFEF; -moz-border-radius: 15px; -webkit-border-radius: 15px; border: 1px solid # C9C9C9;  #search width: 600px; margine: 40px auto; allineamento del testo: centro;  #keyword width: 150px; altezza: 30 px; padding: 0 10px; border: 1px solid # C9C9C9; -moz-border-radius: 5px; -webkit-border-radius: 5px; sfondo: # F0F0F0; font-size: 18px;  # apply-highlight, # remove-highlight padding-left: 40px;  .highlight background-color: yellow; 

Ancora una volta, abbastanza auto esplicativo e piuttosto semplice. L'unica cosa da notare è la classe chiamata evidenziare che sto definendo. Questo sarà applicato al testo che avremo bisogno di evidenziare.

A questo punto, la tua pagina dovrebbe apparire così:


L'interazione: JavaScript

Il primo ordine del giorno è quello di collegare rapidamente il nostro link con i loro gestori in modo che il testo sia evidenziato e non adeguatamente evidenziato.

 var searchInput = $ ("# keyword"), searchTerm, searchRegex; $ ( "Applica-highlight #") clicca (evidenziare).; $ ("# remove-highlight"). bind ("click", function () $ ("# haiz"). removeHighlight (););

Dovrebbe essere abbastanza semplice. Dichiaro alcune variabili per un uso successivo e allego i collegamenti ai loro gestori. evidenziare e removeHighlight sono funzioni estremamente semplici che vedremo di seguito.

 function highLight () searchTerm = searchInput.val (); searchRegex = new RegExp (searchTerm, 'g'); $ ("# haiz *"). replaceText (searchRegex, ''+ SearchTerm +''); 
  • Ho scelto di creare una funzione vanilla, e non un plugin jQuery, perché sono pigro come una pila di sassi. Iniziamo catturando il valore della casella di input.
  • Successivamente, creiamo un oggetto espressione regolare usando la parola chiave search.
  • Infine, invochiamo il replaceText plugin passando i valori appropriati. Sto scegliendo di includere direttamente termine di ricerca nel markup per brevità.
 jQuery.fn.removeHighlight = function () return this.find ("span.highlight"). each (function () with (this.parentNode) replaceChild (this.firstChild, this););

Un metodo veloce e sporco, hacky per portare a termine il lavoro. E sì, questo è un plugin jQuery dal momento che volevo riscattarmi. La classe è ancora hardcoded però.

Sto solo cercando ogni tag span con una classe di evidenziare e sostituendo l'intero nodo con il valore che contiene.

Prima di preparare i forconi, ricorda che questo è solo a scopo dimostrativo. Per la tua applicazione, avrai bisogno di un metodo di unhighlight molto più sofisticato.


Avvolgendo

E abbiamo finito. Abbiamo dato un'occhiata a un plugin incredibilmente utile, abbiamo analizzato il codice sorgente e alla fine abbiamo creato un mini progetto con esso.