Spotlight jQuery replaceText

Om de week houden we een ultragerichte kijk op een interessant en nuttig effect, plug-in, hack, bibliotheek of zelfs een handige technologie. We proberen dan de code te deconstrueren of er een leuk klein project mee te maken.

Vandaag gaan we kijken naar de excellente replaceText jQuery-plug-in. Geïnteresseerd? Laten we aan de slag na de sprong.


Een woord van de auteur

Als webontwikkelaars hebben we toegang tot een duizelingwekkende hoeveelheid kant-en-klare code, of het nu een klein fragment is of een volledig ontwikkeld raamwerk. Tenzij je iets ongelooflijk speciaals doet, is de kans groot dat er al iets vooraf is voorbereid dat je kunt gebruiken. Jammer genoeg kwijnen veel van deze geweldige aanbiedingen in anonimiteit, speciaal voor de niet-hardcore menigte.

Deze serie probeert dit probleem op te lossen door het introduceren van een aantal echt goed geschreven, nuttige code - zij het een plug-in, een effect of een technologie voor de lezer. Verder, als het klein genoeg is, zullen we proberen de code te deconstrueren en begrijpen hoe het voodoo doet. Als het veel groter is, zullen we proberen om er een miniproject mee te maken om de touwen te leren en hopelijk te begrijpen hoe we het in de echte wereld kunnen gebruiken.


Introductie van replaceText

We trappen dingen af ​​door ons te concentreren op Ben Alman's excellente replaceText plug-in. Hier is wat snelle info:

  • Type: Inpluggen
  • Technologie: JavaScript [Gebouwd op de jQuery-bibliotheek]
  • Schrijver: Ben Alman
  • Functie: Onopvallende, beknopte manier om tekstuele inhoud te vervangen

Het probleem

Het vervangen van inhoud op uw pagina klinkt heel eenvoudig. Immers, de native JavaScript-methode vervangen lijkt hetzelfde te doen. Als je je bijzonder lui voelt, maakt jQuery het ook obsceen gemakkelijk om de hele inhoud van de container te vervangen.

 // Alleen $ vervangen ("# container"). Text (). Replace (/ text / g, 'vervangende tekst') // Vervanging van de * gehele * inhoud van de container var lazyFool = "volledige inhoud met extern vervangen tekst "; . $ ( "# Container") html (lazyFool);

Zoals het gezegde luidt, alleen al omdat je het kunt doen, hoef je niet echt te doen. Beide methoden worden over het algemeen gemeden [buiten randgevallen] omdat ze een heleboel dingen verbreken terwijl ze doen wat ze doen.

Het belangrijkste probleem met deze benaderingen is dat ze de DOM-structuur afvlakken en elk niet-tekstknooppunt dat de container bevat, effectief verprutst. Als het u lukt om de html zelf te vervangen, gebruikt u innerHTML of jQuery's html, je onthoudt nog steeds elke event-handler die aan een van zijn kinderen is gekoppeld, wat een complete deal-breaker is. Dit is het primaire probleem dat deze plug-in lijkt op te lossen.


De oplossing

De beste manier om met de situatie om te gaan, en de manier waarop de plug-in deze verwerkt, is om exclusief met tekstknooppunten te werken en deze aan te passen.

Tekstknooppunten verschijnen in de DOM net als gewone knooppunten, behalve dat ze geen onderliggende knooppunten kunnen bevatten. De tekst die ze bevatten kan worden verkregen met behulp van de nodeValue of gegevens eigendom.

Door met tekstknooppunten te werken, kunnen we veel van de complexiteit van het proces overbruggen. We moeten in essentie de knooppunten doorlopen, testen of het een tekstknoop is en zo ja, doorgaan met het op intelligente wijze manipuleren om problemen te voorkomen.

We zullen de broncode van de plug-in zelf beoordelen, zodat u kunt begrijpen hoe de plug-in dit concept in detail implementeert.


Gebruik

Zoals de meeste goed geschreven jQuery-plug-ins, is dit buitengewoon eenvoudig te gebruiken. Het gebruikt de volgende syntaxis:

$ (container) .replaceText (tekst, vervanging);

Als u bijvoorbeeld alle exemplaren van het woord 'val' moet vervangen door 'waarde', moet u de plug-in bijvoorbeeld zo instantiëren:

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

Ja, het is echt zo simpel. De plug-in zorgt voor alles voor u.

Als jij het soort bent dat met reguliere expressies te slim af is, kun je dat ook doen!

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

U hoeft zich geen zorgen te maken over het vervangen van inhoud in de kenmerken van een element, de plug-in is best slim.


De bron deconstrueren

Omdat de plug-in uit slechts 25 regels bestaat, nemen we, wanneer we ons ontdoen van opmerkingen en dergelijke, snel de bron door met uitleg over welk fragment wat doet en waarvoor.

Hier is de bron, ter referentie. We zullen elk deel hieronder in detail bespreken.

 $ .fn.replaceText = function (zoeken, vervangen, 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 (zoeken, vervangen); if (new_val! == val) if (! text_only && / 

Oké, laten we een redelijk hoog niveau doorlopen van de code.

 $ .fn.replaceText = functie (zoeken, vervangen, text_only) ;

Stap 1 - De generieke wrapper voor een jQuery-plug-in. De auteur heeft terecht afgezien van het toevoegen van vapide opties omdat de geboden functionaliteit eenvoudig genoeg is om er een te rechtvaardigen. De parameters moeten voor zichzelf spreken -- alleen tekst zal een beetje later worden behandeld.

 return this.each (function () );

Stap 2 - this.each zorgt ervoor dat de plug-in zich gedraagt ​​wanneer de plug-in wordt doorgegeven in een verzameling elementen.

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

Stap 3 - Vereiste aangifte van de variabelen die we gaan gebruiken.

  • knooppunt houdt het eerste onderliggende element van het knooppunt vast.
  • val houdt de huidige waarde van het knooppunt vast.
  • new_val bevat de bijgewerkte waarde van het knooppunt.
  • verwijderen is een array die een knoop zal bevatten die uit de DOM moet worden verwijderd. Ik zal hier in een beetje in detail op in gaan.
 if (node) 

Stap 4 - We controleren of het knooppunt daadwerkelijk bestaat, d.w.z. de container die is doorgegeven heeft onderliggende elementen. Onthoudt dat knooppunt bevat het eerste onderliggende element van het doorgegeven element.

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

Stap 5 - De lus draait, in wezen, door de kindknooppunten die eindigen als de lus zich bij het laatste knooppunt bevindt.

 if (node.nodeType === 3) 

Stap 6 - Dit is het interessante deel. We hebben toegang tot de nodeType eigenschap [alleen-lezen] van het knooppunt om te bepalen welk type knooppunt het is. Een waarde van 3 houdt in dat dit een tekstknooppunt is, dus we kunnen doorgaan. Als het je het leven gemakkelijker maakt, kun je het als volgt herschrijven: if (node.nodeType == Node.TEXT_NODE) ​​.

 val = node.nodeValue; new_val = val.replace (zoeken, vervangen);

Stap 7 - We slaan de huidige waarde van het tekstknooppunt op, eerst omhoog. Vervolgens vervangen we snel exemplaren van het zoekwoord door de vervanging door de native vervangen JavaScript-methode. De resultaten worden opgeslagen in de variabele new_val.

 if (new_val! == val) 

Stap 8 - Ga alleen verder als de waarde is gewijzigd!

 if (! text_only && / 

Stap 9a - Herinner de alleen tekst parameter. Dit komt hier om de hoek kijken. Dit wordt gebruikt om aan te geven of de container moet worden behandeld als een die elementknopen bevat. De code voert ook een snelle interne controle uit om te zien of deze HTML-inhoud bevat. Het doet dit door te zoeken naar een openingstag in de inhoud van new_val.

Zo ja, dan wordt de a-tekstknoop ingevoegd vóór het huidige knooppunt en wordt het huidige knooppunt toegevoegd aan het verwijderen array die later moet worden verwerkt.

 else node.nodeValue = new_val; 

Stap 9b - Als het alleen maar tekst is, injecteer dan de nieuwe tekst rechtstreeks in het knooppunt zonder door de DOM-jongleerhallo te gaan.

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

Stap 10 - Eindelijk, als de loop eenmaal is afgelopen, verwijderen we snel de geaccumuleerde knooppunten uit de DOM. De reden dat we het doen nadat de lus is afgelopen, is dat het verwijderen van een knooppunt in de loop van de loop de lus zelf verknoeit.


project

Het kleine project dat we vandaag gaan bouwen is vrij eenvoudig. Hier is de lijst met onze vereisten:

  • Primaire eis: Een highlight-effect toepassen op tekst die is geëxtraheerd uit gebruikersinvoer. Dit moet volledig worden verzorgd door de plug-in.
  • Secundaire eis: Hoogtepunt onmiddellijk verwijderen, indien nodig. We zullen een klein codefragment aan het opnemen zijn om dit te helpen. Niet productiegereed maar zou het wel goed moeten doen voor onze doeleinden.

Notitie: Dit is meer een proof of concept dan iets dat je gewoon onaangeroerd kunt inzetten. Vanzelfsprekend heb ik in het belang van het voorkomen dat het artikel ongeslacht wordt, een aantal secties overgeslagen die van het grootste belang zijn voor productiegereedbare codevalidatie, bijvoorbeeld.

De werkelijke focus moet hier liggen op de plug-in zelf en de ontwikkelingstechnieken die het bevat. Vergeet niet dat dit meer een bètagemo is om iets cools te laten zien dat met deze plug-in kan worden gedaan. Altijd uw invoer zuiveren en valideren!


De stichting: HTML en CSS

    Deconstruction: jQuery replaceText    

Deconstruction: jQuery replaceText

door Siddharth voor de lieve mensen bij Nettuts+

Deze pagina gebruikt de populaire replaceText-plugin van Ben Alman. In deze demo gebruiken we het om willekeurige stukjes tekst op deze pagina te markeren. Vul het woord in, je bent op zoek naar en klik op start.

Pas highlight toe

<-- Assorted text here -->

De HTML moet behoorlijk verklarend zijn. Ik heb alleen een tekstinvoer gemaakt, twee koppelingen om de markering toe te passen en te verwijderen, evenals een alinea met een aantal gesorteerde tekst.

 lichaam font-family: "Myriad Pro", "Lucida Grande", "Verdana", sans-serif; lettergrootte: 16px;  p margin: 20px 0 40px 0;  h1 font-size: 36px; opvulling: 0; marge: 7px 0;  h2 font-size: 24px;  #container width: 900px; marge links: auto; marge-rechts: auto; opvulling: 50px 0 0 0; positie: relatief;  #haiz opvulling: 20px; achtergrond: #EFEFEF; -moz-border-radius: 15px; -webkit-border-radius: 15px; rand: 1px vast # C9C9C9;  #search width: 600px; marge: 40 px auto; text-align: center;  #keyword width: 150px; hoogte: 30 px; opvulling: 0 10px; rand: 1px vast # C9C9C9; -moz-border-radius: 5px; -webkit-border-radius: 5px; achtergrond: # F0F0F0; lettergrootte: 18px;  # apply-highlight, # remove-highlight padding-left: 40px;  .licht achtergrondkleur: geel; 

Nogmaals, vrij duidelijk en vrij basic. Het enige dat op te merken is, is de klasse genaamd hoogtepunt die ik definieer. Dit wordt toegepast op de tekst die we moeten markeren.

In dit stadium zou uw pagina er als volgt uit moeten zien:


De interactie: JavaScript

De eerste volgorde van de dag is om snel onze link met hun handlers aan te maken, zodat de tekst op de juiste manier wordt gemarkeerd en onbelicht.

 var searchInput = $ ("# keyword"), searchTerm, searchRegex; $ ( "# Toepassing-highlight") klikken (markeren).; $ ("# remove-highlight"). bind ("klik", functie () $ ("# haiz"). removeHighlight (););

Moet vrij eenvoudig zijn. Ik verklaar een paar variabelen voor later gebruik en voeg de links toe aan hun handlers. highlight en removeHighlight zijn uiterst eenvoudige functies die we hieronder zullen bekijken.

 function highLight () searchTerm = searchInput.val (); searchRegex = nieuwe RegExp (searchTerm, 'g'); $ ("# haiz *"). replaceText (searchRegex, ''+ Zoekterm +''); 
  • Ik heb ervoor gekozen om een ​​vanillefunctie te maken, en geen plug-in voor jQuery, omdat ik lui ben als een stapel stenen. We beginnen met het vastleggen van de waarde van de invoerbox.
  • Vervolgens maken we met behulp van het zoekwoord een expressieobject.
  • Ten slotte roepen we de replaceText plug-in door de juiste waarden door te geven. Ik kies ervoor om direct op te nemen zoekterm in de opmaak voor beknoptheid.
 jQuery.fn.removeHighlight = function () return this.find ("span.highlight"). each (function () with (this.parentNode) replaceChild (this.firstChild, this););

Een snelle en vuile hack-methode om de klus te klaren. En ja, dit is een jQuery plug-in omdat ik mezelf wilde verzilveren. De klasse is nog steeds hard gecodeerd.

Ik ben alleen op zoek naar elke span-tag met een klasse van hoogtepunt en het vervangen van het volledige knooppunt door de waarde die het bevat.

Voordat je je pitchforks klaar krijgt, bedenk dan dat dit alleen voor demonstratiedoeleinden is. Voor uw eigen toepassing heeft u een veel geavanceerdere methode voor ongemarkeerd licht nodig.


Afsluiten

En we zijn klaar. We hebben een ongelooflijk nuttige plug-in bekeken, de broncode doorlopen en uiteindelijk klaar met het maken van een miniproject.