Hver annen uke tar vi et ultrafokusert utseende på en interessant og nyttig effekt, plugin, hack, bibliotek eller til og med en grei teknologi. Vi forsøker da å dekonstruere koden eller lage et morsomt lite prosjekt med det.
I dag skal vi se på det gode erstatteText jQuery-plugin. Interessert? La oss komme i gang etter hoppet.
Som webutviklere har vi tilgang til en svimlende mengde forhåndsbygget kode, enten det er et lite stykke eller et fullverdig rammeverk. Med mindre du gjør noe utrolig spesifikt, er det sjansene, det er allerede noe prebuilt for deg å utnytte. Dessverre slår mange av disse stjernene i anonymitet, spesielt til de ikke-hardcore publikum.
Denne serien søker å rette opp dette problemet ved å introdusere noen virkelig godt skrevet, nyttig kode - det være seg en plugin, effekt eller en teknologi til leseren. Videre, hvis det er lite nok, forsøker vi å dekonstruere koden og forstå hvordan den gjør det voodoo. Hvis det er mye større, vil vi forsøke å lage et mini-prosjekt med det for å lære tauene og forhåpentligvis forstå hvordan gjøre bruk av det i den virkelige verden.
Vi sparker av ting ved å fokusere på Ben Almans fremragende erstatningstekst-plugin. Her er litt rask info:
Bytte ut innhold på siden din lyder ekstremt enkelt. Tross alt, den innfødte JavaScript-metoden erstatte
ser ut til å gjøre det samme. Hvis du føler deg spesielt lat, gjør jQuery erstatning for hele innholdet i beholderen uanstendig lett også.
// erstatte (/ tekst / g, erstatningstekst) // Bytte ut hele innholdet i beholderen var lazyFool = "Hele innholdet med tekst erstattet eksternt "; . $ ( "# Container") html (lazyFool);
Som det sier, bare fordi du kan gjøre det, betyr det egentlig ikke at du skal gjøre det. Begge disse metodene blir vanligvis fjernet [utenfor kantsaker] fordi de bryr en mengde ting mens de gjør det de gjør.
Hovedproblemet med disse tilnærmingene er at de flater DOM-strukturen effektivt og skruer opp hver ikke-tekst-node beholderen holder. Hvis du klarer å erstatte selve html, bruker du innerhtml
eller jQuery s html
, Du vil fortsatt avhende hver hendelsehandler knyttet til noen av sine barn, som er en komplett avtalebryter. Dette er det primære problemet dette pluginet ser ut til å løse.
Den beste måten å håndtere situasjonen på, og hvordan plugin håndterer den, er å jobbe med og endre tekstnoder utelukkende.
Tekstnoder vises i DOM, akkurat som vanlige noder, bortsett fra at de ikke kan inneholde barnnodes. Teksten de holder kan fås ved å bruke enten
nodevalue
ellerdata
eiendom.
Ved å jobbe med tekstnoder kan vi gjøre mange av de kompleksitetene som er involvert i prosessen. Vi må i hovedsak gå gjennom noder, teste om det er en tekstknute og hvis ja, fortsett å manipulere det intelligent for å unngå problemer.
Vi vurderer kildekoden til pluginet selv, slik at du kan forstå hvordan plugin implementerer dette konseptet i detalj.
Som de fleste godt skrevet jQuery-plugins, er dette ekstremt enkelt å bruke. Den bruker følgende syntaks:
$ (container) .replaceText (tekst, erstatning);
For eksempel, hvis du trenger å erstatte alle forekomster av ordet "val" med "verdi", for eksempel, må du instille pluginet slik:
$ ("# container"). erstatte tekst ("val", "verdi");
Ja, det er veldig enkelt. Pluggen tar seg av alt for deg.
Hvis du er den typen som går amok med vanlige uttrykk, kan du også gjøre det!
$ ("# container"). erstatte tekst (/ (val) / gi, "verdi");
Du trenger ikke bekymre deg for å erstatte innhold i et elements attributter, pluggen er ganske smart.
Siden plugin er laget av bare 25 kodelinjer, når du fjerner kommentarer og slik, vil vi gjøre en rask gjennomgang av kilden som forklarer hvilken kodebit som gjør hva og for hvilket formål.
Her er kilden, for din referanse. Vi vil gå over hver del i detalj nedenfor.
$ .fn.replaceText = funksjon (søk, erstatt, tekst_only) return this.each (funksjon () var node = this.firstChild, val, new_val, remove = []; hvis (node) do if .nodeType === 3) val = node.nodeValue; new_val = val.replace (søk, erstatt); hvis (new_val! == val) if (! text_only && /Riktig, la oss gjøre et moderat høyt nivå gjennom koden.
$ .fn.replaceText = funksjon (søk, erstatt, tekst_only) ;Trinn 1 - Den generiske omslaget for en jQuery-plugin. Forfatteren har med rette avholdt seg fra å legge til våpenalternativer, siden funksjonaliteten som er gitt er enkel nok til å garantere en. Parametrene skal være selvforklarende --
text_only
vil bli håndtert litt senere.returner this.each (funksjon () );Steg 2 -
this.each
sørger for at plugin oppfører seg når pluginet er sendt i en samling av elementer.var node = this.firstChild, val, new_val, remove = [];Trinn 3 - Nødvendig erklæring om variablene vi skal bruke.
node
holder nodens første barnelement.val
holder nodens nåværende verdi.new_val
holder den oppdaterte verdien av noden.fjerne
er en matrise som vil inneholde knutepunktet som må fjernes fra DOM. Jeg skal gå nærmere om dette på litt.hvis (node)
Trinn 4 - Vi kontrollerer om noden egentlig eksisterer, dvs. beholderen som ble sendt inn, har barnelementer. Husk at node
har bestått elementets første barnelement.
gjør mens (node = node.nextSibling);
Trinn 5 - Sløyfen i det hele tatt, vel, sløyer seg gjennom barnens noder etterbehandling når sløyfen er på den endelige noden.
hvis (node.nodeType === 3)
Trinn 6 - Dette er den interessante delen. Vi får tilgang til Nodetype
eiendom [skrivebeskyttet] til noden for å utlede hvilken type node det er. En verdi på 3 innebærer at det er en tekstknute, så vi kan fortsette. Hvis det gjør livet enklere for deg, kan du omskrive det slik: hvis (node.nodeType == Node.TEXT_NODE)
.
val = node.nodeValue; new_val = val.replace (søk, erstatt);
Trinn 7 - Vi lagrer gjeldende verdi av tekstnoden, først opp. Deretter erstatter vi raskt forekomster av søkeordet med erstatning med den innfødte erstatte
JavaScript-metode. Resultatene lagres i variabelen new_val
.
hvis (new_val! == val)
Trinn 8 - Fortsett bare hvis verdien er endret!
hvis (! text_only && /Trinn 9a - Husk
text_only
parameter. Dette kommer inn i spill her. Dette brukes til å angi om beholderen skal behandles som en som inneholder elementnoder inne. Koden gjør også en rask intern kontroll for å se om den inneholder HTML-innhold. Det gjør det ved å lete etter en åpningsmerke i innholdet inew_val
.Hvis ja, er en tekstnode satt inn før gjeldende knutepunkt og nåværende knutepunkt er lagt til i
fjerne
array som skal håndteres senere.ellers node.nodeValue = new_val;Trinn 9b - Hvis det bare er tekst, injiser du den nye teksten direkte inn i noden uten å gå gjennom DOM jonglering hoopla.
remove.length && $ (remove) .remove ();Trinn 10 - Til slutt, når sløyfen er ferdig, fjerner vi raskt de akkumulerte noder fra DOM. Grunnen til at vi gjør det etter at løkken er fullført, er at det å fjerne en knutepunkt i midten vil skru opp løkken selv.
Prosjekt
Det lille prosjektet vi skal bygge i dag er ganske grunnleggende. Her er listen over våre krav:
Merk: Dette er mer et bevis på konsept enn noe du bare kan distribuere uberørt. For å forhindre at artikkelen blir ujevn, har jeg åpenbart hoppet over en rekke seksjoner som er av største betydning for produksjonsklar kode - validering for eksempel.
Selve fokus her bør være på selve plugin og utviklingsteknikkene som den inneholder. Husk, dette er mer av en beta-demo som viser noe kul som kan gjøres med dette pluginet. Alltid hygge og validere dine innganger!
Dekonstruksjon: jQuery replaceText Dekonstruksjon: jQuery replaceText
av Siddharth for de nydelige folkene på Nettuts+Denne siden bruker den populære erstatteText-plugin av Ben Alman. I denne demoen bruker vi den til å markere vilkårlig biter av tekst på denne siden. Fyll ut ordet, du leter etter og treffer gå.
<-- Assorted text here -->
HTML-en skal være ganske forklarende. Alt jeg har gjort er å lage en tekstinnføring, to koblinger for å søke på og fjerne høydepunktet, samt et avsnitt som inneholder litt assosiert tekst.
kropp font-family: "Myriad Pro", "Lucida Grande", "Verdana", sans-serif; skriftstørrelse: 16px; p margin: 20px 0 40px 0; h1 skriftstørrelse: 36px; polstring: 0; margin: 7px 0; h2 font-size: 24px; #container width: 900px; margin-left: auto; margin-høyre: auto; polstring: 50px 0 0 0; stilling: relativ; #haiz polstring: 20px; bakgrunn: #EFEFEF; -moz-border-radius: 15px; -webkit-grense-radius: 15px; grense: 1px solid # C9C9C9; #search bredde: 600px; margin: 40px auto; tekst-align: center; #keyword width: 150px; høyde: 30px; polstring: 0 10px; grense: 1px solid # C9C9C9; -moz-border-radius: 5 px; -webkit-grense-radius: 5px; bakgrunn: # F0F0F0; skriftstørrelse: 18px; # apply-highlight, # remove-highlight polstring-venstre: 40px; .highlight bakgrunnsfarger: gul;
Igjen, ganske selvforklarende og ganske grunnleggende. Det eneste å merke seg er klassen kalt fremheve
som jeg definerer. Dette vil bli brukt på teksten som vi må markere.
På dette stadiet bør siden din se slik ut:
Første ordre av dagen er å raskt koble opp vår lenke med deres håndterer, slik at teksten er uthevet og ubelagt riktig.
var searchInput = $ ("# søkeord"), searchTerm, searchRegex; $ ( "# Søke-marker") klikk (Høydepunkt).; $ ("# remove-highlight"). bind ("klikk", funksjon () $ ("# haiz"). removeHighlight (););
Bør være ganske enkelt. Jeg erklærer noen variabler for senere bruk og legger til koblingene til deres håndtere. fremheve
og removeHighlight
er ekstremt enkle funksjoner vi ser nedenfor.
funksjon highLight () searchTerm = searchInput.val (); searchRegex = ny RegExp (searchTerm, 'g'); $ ("# haiz *"). replaceText (searchRegex, ''+ SEARCH +'');
replaceText
plugin ved å passere i de riktige verdiene. Jeg velger å inkludere direkte søkeord
i oppslaget for korthet.jQuery.fn.removeHighlight = function () return this.find ("span.highlight"). hver (funksjon () med this.parentNode replaceChild (this.firstChild, dette););
En rask og skitten, hacky metode for å få jobben gjort. Og ja, dette er et jQuery-plugin siden jeg ønsket å innløse meg selv. Klassen er fortsatt hardkodet skjønt.
Jeg ser bare etter hvert span-tag med en klasse av fremheve
og erstatte hele noden med verdien den inneholder.
Før du får dine pitchforks klar, husk at dette bare er for demonstrasjonsformål. For din egen applikasjon trenger du en mye mer sofistikert unhighlight-metode.
Og vi er ferdige. Vi tok en titt på et utrolig nyttig plugin, gikk gjennom kildekoden og til slutt avsluttet ved å lage et mini-prosjekt med det.