Lumina reflectoarelor jQuery replaceText

În fiecare săptămână, vom analiza cu atenție un aspect interesant și util, plugin, hack, bibliotecă sau chiar o tehnologie minunată. Vom încerca apoi fie să deconstruăm codul, fie să creăm un mic proiect distractiv.

Astăzi, vom analiza pluginul excelent replaceText jQuery. Interesat? Să începem după salt.


Un Cuvânt al autorului

În calitate de dezvoltatori web, avem acces la o sumă uimitoare de cod pre-construit, fie că este vorba de un fragment mic sau de un cadru complet. Dacă nu faci ceva incredibil de specific, există șanse, există deja ceva preconfirmat pentru a vă folosi. Din nefericire, multe dintre aceste oferte stelare se distrug în anonimitate, în special pentru mulțimea non-hardcore.

Această serie urmărește să remedieze această problemă introducând un cod cu adevărat bine scris și util - fie un plugin, un efect sau o tehnologie pentru cititor. Mai mult, dacă este suficient de mic, vom încerca să deconstruăm codul și să înțelegem cum o face voodoo. Dacă este mult mai mare, vom încerca să creăm un mini-proiect cu el pentru a învăța funiile și, sperăm, să înțelegem cum îl folosim în lumea reală.


Introducerea înlocuirii textului

Începem lucrurile concentrându-ne pe pluginul excelent înlocuitor al lui Ben Alman. Iată câteva informații rapide:

  • Tip: Conecteaza
  • Tehnologie: JavaScript [Construit pe biblioteca jQuery]
  • Autor: Ben Alman
  • Funcţie: Modul neobișnuit și concis pentru a înlocui conținutul textual

Problema

Înlocuirea conținutului în pagină este extrem de simplă. La urma urmei, metoda JavaScript nativă a inlocui pare să facă același lucru. Dacă vă simțiți deosebit de leneș, jQuery face înlocuirea întregului conținut al containerului și obscen ușor.

 // Înlocuirea conținutului * întreg * al containerului var lazyFool = "întregul conținut cu textul înlocuit extern „; . $ ( "# Container") html (lazyFool);

Așa cum se spune, doar pentru că poți să faci asta nu înseamnă că ar trebui să faci. Ambele metode sunt, în general, evitate [în afara cazurilor de margine], deoarece rupe o grămadă de lucruri în timp ce fac ceea ce fac.

Principala problemă cu aceste abordări este aceea de a aplati structura DOM în mod eficient prin înșurubarea fiecărui nod netextar pe care îl are containerul. Dacă reușiți să înlocuiți html-ul în sine, utilizând innerHTML sau jQuery html, totuși, veți debloca fiecare manipulator de evenimente atașat oricăruia dintre copiii săi, ceea ce reprezintă o întrerupere completă a afacerilor. Aceasta este problema principală pe care acest plugin pare să o rezolve.


Soluția

Cea mai bună modalitate de a face față situației și modul în care plugin-ul se ocupă de aceasta este să lucreze cu și să modifice exclusiv nodurile text.

Nodurile de text apar în DOM la fel ca nodurile obișnuite, cu excepția faptului că nu pot conține copii. Textul pe care îl dețin poate fi obținut utilizând fie nodeValue sau date proprietate.

Lucrând cu noduri de text, putem face o mulțime de complexități implicate în proces. Vom avea nevoie, în esență, să buclele prin noduri, să testați dacă este vorba de un nod text și, dacă da, să continuați să îl manipulați inteligent pentru a evita problemele.

Vom revizui codul sursă al plugin-ului însuși pentru a înțelege modul în care plugin-ul implementează acest concept în detaliu.


folosire

Ca cele mai bune plug-in-uri jQuery, acest lucru este extrem de ușor de utilizat. Utilizează următoarea sintaxă:

$ (container) .replaceText (text, înlocuire);

De exemplu, dacă trebuie să înlocuiți toate aparițiile cuvântului "val" cu "valoare", de exemplu, va trebui să instanțiați pluginul după cum urmează:

 $ ("container"). replaceText ("val", "valoare");

Da, e foarte simplu. Pluginul are grijă de tot pentru dvs..

Dacă sunteți tipul care merge amok cu expresii regulate, puteți face și asta!

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

Nu trebuie să vă faceți griji cu privire la înlocuirea conținutului în atributele unui element, pluginul este destul de inteligent.


Deconstruirea sursei

Deoarece plugin-ul este format din numai 25 de linii de cod, atunci când este dezbrăcat de comentarii și așa, vom face o scurtă scurgere a sursei explicând ce fragment face ce și în ce scop.

Iată sursa, pentru referință. Vom trece fiecare detaliu mai jos.

 $ .fn.replaceText = funcția (căutare, înlocuire, text_only) return this.each (function () var node = this.firstChild, val, new_val, remove = []; .nodeType === 3) val = node.nodeValue; new_val = val.replace (căutare, înlocuire); dacă (new_val! == val) if (! text_only && / 

Corect, să facem un nivel moderat de alergare a codului.

 $ .fn.replaceText = funcție (căutare, înlocuire, text_only) ;

Pasul 1 - Inventatorul generic pentru un plugin jQuery. Autorul, pe bună dreptate, sa abținut de la adăugarea opțiunilor vapid, deoarece funcționalitatea oferită este suficient de simplă pentru a justifica una. Parametrii trebuie să fie explicativi -- doar text vor fi tratate un pic mai târziu.

 returnați acest lucru (funcția () );

Pasul 2 - this.each asigurați-vă că plugin-ul se comportă atunci când plugin-ul este trecut într-o colecție de elemente.

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

Pasul 3 - Declarație obligatorie a variabilelor pe care le vom folosi.

  • nodul ține primul element copil al nodului.
  • Val menține valoarea actuală a nodului.
  • new_val păstrează valoarea actualizată a nodului.
  • elimina este o matrice care va conține nod care va trebui eliminat din DOM. Mă duc în detaliu despre asta puțin.
 dacă (nod) 

Pasul 4 - Verificăm dacă nodul există, adică containerul care a fost transmis are elemente elementare. Sa nu uiti asta nodul ține primul element copil al elementului trecut.

  în timp ce (node ​​= node.nextSibling);

Pasul 5 - Buclele în esență, bine, buclele prin nodurile copilului terminând când bucla se află la nodul final.

 dacă (node.nodeType === 3) 

Pasul 6 - Aceasta este partea interesantă. Accesăm nodeType proprietate [read-only] a nodului pentru a deduce ce fel de nod este. O valoare de 3 implică faptul că este un nod de text, așa că putem continua. Dacă vă ușurează viața, o puteți rescrie astfel: dacă (node.nodeType == Node.TEXT_NODE) ​​.

 val = node.nodeValue; new_val = val.replace (căutare, înlocuire);

Pasul 7 - Stocăm valoarea curentă a nodului text, în primul rând. Apoi, înlocuim repede instanțele cuvântului cheie cu înlocuitorul cu limba nativă a inlocui Metoda JavaScript. Rezultatele sunt stocate în variabilă new_val.

 dacă (new_val! == val) 

Pasul 8 - Procedați numai dacă valoarea sa modificat!

 dacă (! text_only && / 

Pasul 9a - Amintiți-vă doar text parametru. Aici intră aici. Acesta este folosit pentru a specifica dacă recipientul trebuie tratat ca unul care conține noduri de elemente din interior. De asemenea, codul face o verificare internă rapidă pentru a vedea dacă conține conținut HTML. Ea face acest lucru prin căutarea unei etichete de deschidere în conținutul new_val.

Dacă da, un textnode este introdus înaintea nodului curent și nodul curent este adăugat la elimina array să fie tratate mai târziu.

 altfel node.nodeValue = new_val; 

Etapa 9b - Dacă este doar text, injectați direct noul text în nod fără a trece prin hoopla DOM jonglarea.

 remove.length && $ (eliminați) .remove ();

Pasul 10 - În cele din urmă, odată ce buclele au terminat de parcurs, eliminăm rapid nodurile acumulate din DOM. Motivul pentru care o facem după ce bucla a terminat să fie difuzată este că îndepărtarea unui nod la jumătatea rundei va înșuruba bucla în sine.


Proiect

Proiectul mic pe care îl vom construi astăzi este destul de fundamental. Iată lista cerințelor noastre:

  • Cerința primară: Aplicarea unui efect de evidențiere a textului extras din intrarea utilizatorului. Acest lucru ar trebui să fie luate în considerare complet de plugin.
  • Cerință secundară: Scoaterea evidențierii în zbor, după cum este necesar. Vom bate un mic fragment de cod pentru a ajuta la asta. Nu este gata de producție, ci ar trebui să facă destul de bine pentru scopurile noastre.

Notă: Aceasta este mai mult o dovadă a conceptului decât ceva pe care îl puteți desfășura doar neatins. Evident, în interesul de a împiedica articolul să devină nenorocit, am omis un număr de secțiuni care sunt de o importanță majoră pentru validarea codului de producție, de exemplu.

Actualul accent ar trebui să fie pus pe plugin-ul propriu-zis și pe tehnicile de dezvoltare pe care le conține. Amintiți-vă, acest lucru este mai mult de un demo beta pentru a prezenta ceva cool care se poate face cu acest plugin. Întotdeauna sanitizați și validați datele introduse!


Fundația: HTML și CSS

    Deconstrucție: jQuery replaceText    

Deconstrucție: jQuery replaceText

de Siddharth pentru cei minunați de la Nettuts+

Această pagină utilizează pluginul popular replaceText de Ben Alman. În acest demo, îl folosim pentru a evidenția bucăți arbitrare de text de pe această pagină. Completați cuvântul, căutați și du-te du-te.

Aplicați evidențierea highlightRemove

<-- Assorted text here -->

HTML-ul ar trebui să fie destul de explicativ. Tot ce am făcut este să creez o introducere de text, două linkuri pentru a aplica și elimina accentul, precum și un paragraf care conține un text asortat.

 corp font-family: "Myriad Pro", "Lucida Grande", "Verdana", sans serif; font-size: 16px;  p marja: 20px 0 40px 0;  h1 font-size: 36px; umplutura: 0; margine: 7px 0;  h2 font-size: 24px;  #container width: 900px; margin-stânga: auto; margin-dreapta: auto; padding: 50px 0 0 0; poziție: relativă;  #haiz padding: 20px; fundal: #EFEFEF; -moz-border-radius: 15px; -webkit-border-radius: 15px; frontieră: 1px solid # C9C9C9;  #search width: 600px; margine: 40 pixeli auto; text-align: centru;  #keyword width: 150px; înălțime: 30px; umplutură: 0 10px; frontieră: 1px solid # C9C9C9; -moz-border-radius: 5px; -webkit-border-radius: 5px; fundal: # F0F0F0; font-size: 18px;  # apply-highlight, # eliminați-evidențiați padding-left: 40px; . culoare (fundal-culoare: galben; 

Din nou, destul de auto-explicativ și destul de bază. Singurul lucru de remarcat este clasa numită a sublinia pe care o definesc. Acest lucru va fi aplicat textului pe care va trebui să îl evidențiăm.

În această etapă, pagina dvs. ar trebui să arate astfel:


Interacțiunea: JavaScript

Prima ordine a zilei este să conectăm rapid legătura noastră cu agenții lor, astfel încât textul să fie evidențiat și neînlăturat în mod corespunzător.

 var searchInput = $ ("# cuvânt cheie"), searchTerm, searchRegex; $ ( "# Aplică-evidenția") click (subl).; $ ("remove-highlight"). () () () ().

Ar trebui să fie destul de simplu. Declar câteva variabile pentru utilizarea ulterioară și atașați legăturile la agenții lor. a sublinia și removeHighlight sunt funcții extrem de simple pe care le vom analiza mai jos.

 funcția highLight () searchTerm = searchInput.val (); searchRegex = RegExp nou (searchTerm, 'g'); $ ("# haiz *") înlocuireText (searchRegex, ''+ SEARCHTERM +'„); 
  • Am ales să creez o funcție de vanilie și nu un plugin jQuery, pentru că sunt leneș ca o grămadă de pietre. Începem prin capturarea valorii casetei de intrare.
  • În continuare, vom crea un obiect de expresie obișnuită utilizând cuvântul cheie de căutare.
  • În cele din urmă, invocăm replaceText plugin prin trecerea în valorile corespunzătoare. Am ales să includ direct termen de căutare în marcarea pentru scurtcircuit.
 jQuery.fn.removeHighlight = funcția () return this.find ("span.highlight") fiecare (funcția () cu (this.parentNode) replaceChild (this.firstChild, this););

O metodă rapidă și murdară, proastă pentru a face treaba. Și da, acesta este un plugin jQuery de când vroiam să mă răscumpăr. Clasa este, totuși, hardcoded.

Căut doar pentru fiecare etichetă cu o clasă de a sublinia și înlocuirea întregului nod cu valoarea pe care o conține.

Înainte de a vă pregăti furcile, amintiți-vă că acest lucru este doar pentru scopuri demonstrative. Pentru propria aplicație, veți avea nevoie de o metodă mult mai sofisticată.


Înfășurarea în sus

Și am terminat. Am aruncat o privire la un plugin incredibil de util, am trecut prin codul sursă și, în final, am terminat prin crearea unui proiect miniatural cu acesta.

Cod