Vartannat vecka tar vi ett ultrafokuserat utseende på en intressant och användbar effekt, plugin, hack, bibliotek eller till och med en snygg teknik. Vi försöker sedan antingen dekonstruera koden eller skapa ett roligt litet projekt med det.
Idag ska vi titta på det utmärkta replaceText jQuery-plugin. Intresserad? Låt oss komma igång efter hoppet.
Som webbutvecklare har vi tillgång till en svimlande mängd förbyggd kod, vare sig det är ett litet fragment eller en fullsträckt ram. Om du inte gör något oerhört specifikt, är chansen att det redan finns något förbyggt för att du ska kunna utnyttja. Tyvärr försvinner många av dessa stellära erbjudanden i anonymitet, speciellt för de icke-hardcore publiken.
Denna serie syftar till att åtgärda problemet genom att införa en riktigt välskriven, användbar kod - vare sig det är en plugin, effekt eller en teknik för läsaren. Vidare, om det är tillräckligt liten, försöker vi dekonstruera koden och förstå hur den gör det voodoo. Om det är mycket större, försöker vi skapa ett mini-projekt med det för att lära sig repen och förhoppningsvis förstå hur använda det i den verkliga världen.
Vi sparkar av saker genom att fokusera på Ben Almans utmärkta ersättnings-plugin. Här är några snabba info:
Byte av innehåll på din sida låter extremt enkelt. Trots allt, den inbyggda JavaScript-metoden byta ut
verkar göra samma sak. Om du känner dig särskilt lat, gör jQuery ersättning för hela innehållet i behållaren obscenely easy too.
// Byt ut bara $ ("# container"). Text (). Ersätt (/ text / g, "ersättningstext") // Byta innehållet * hela * i varan var lazyFool = "Hela innehållet med text ersatt externt "; . $ ( "# Container") html (lazyFool);
Som ordspråket säger, bara för att du kan göra det betyder inte riktigt att du borde göra det. Båda dessa metoder är generellt avskräckta [utanför kantfall] eftersom de brister en massa saker samtidigt som de gör vad de gör.
Huvudproblemet med dessa tillvägagångssätt är att de platta DOM-strukturen effektivt och skruvar upp varje icke-textnod som behållaren rymmer. Om du lyckas ersätta html själv använder du innerhtml
eller jQuery s html
, du kommer fortfarande att haka av varje händelsehanterare som är kopplad till någon av sina barn, vilket är en komplett affärsbrott. Detta är det primära problemet som detta plugin ser ut att lösa.
Det bästa sättet att hantera situationen och hur plugin hanterar det är att arbeta med och modifiera textnoder uteslutande.
Textnoder visas i DOM, precis som vanliga noder, förutom att de inte kan innehålla barnnoder. Texten de håller kan erhållas med antingen
nodevalue
ellerdata
fast egendom.
Genom att arbeta med textnoder kan vi göra mycket av de komplexa som är inblandade i processen. Vi behöver väsentligen slinga genom noderna, testa om det är en textnod och om ja, fortsätt att manipulera det intelligent för att undvika problem.
Vi granskar källkoden för plugin-enheten så att du kan förstå hur pluginet implementerar detta koncept i detalj.
Liksom de flesta välskrivna jQuery-plugins är detta extremt lätt att använda. Den använder följande syntax:
$ (container) .replaceText (text, ersättning);
Om du till exempel måste ersätta alla förekomster av ordet "val" med "värde", måste du till exempel instansera plugin så här:
$ ("# container"). replaceText ("val", "value");
Ja, det är verkligen så enkelt. Pluggen tar hand om allt för dig.
Om du är den typ som går amok med reguljära uttryck, kan du också göra det!
$ ("# container"). ersättText (/ (val) / gi, "värde");
Du behöver inte oroa dig för att ersätta innehållet i ett elements attribut, plugin är ganska smart.
Eftersom plugin är tillverkad av endast 25 kodrubriker, när det tas bort kommentarer och så kommer vi att göra en snabb genomgång av källan som förklarar vilket kodavsnitt som gör vilket och för vilket syfte.
Här är källan, för din referens. Vi kommer att gå över varje del i detalj nedan.
$ .fn.replaceText = funktion (sök, ersätt, text_only) return this.each (funktion ) var node = this.firstChild, val, new_val, remove = []; if (node) gör om .nodeType === 3) val = node.nodeValue; new_val = val.replace (sök, ersätt); om (new_val! == val) if (! text_only && /Låt oss göra en måttlig hög nivå köra igenom koden.
$ .fn.replaceText = funktion (sök, ersätt, text_only) ;Steg 1 - Den generiska omslaget för ett jQuery-plugin. Författaren har med rätta avstått från att lägga till vapidalternativ eftersom funktionaliteten som tillhandahålls är enkel att garantera en. Parametrarna bör vara självförklarande --
text endast
kommer att hanteras lite senare.returnera this.each (funktion () );Steg 2 -
this.each
ser till att plugin beter sig när plugin passeras i en samling element.var node = this.firstChild, val, new_val, remove = [];Steg 3 - Nödvändig deklaration av de variabler vi ska använda.
nod
håller nodens första barnelement.val
håller nodens nuvärde.new_val
håller uppdaterat värde för noden.ta bort
är en array som innehåller nod som måste tas bort från DOM. Jag kommer att gå in i detalj om detta på lite.om (nod)
Steg 4 - Vi kontrollerar om noden faktiskt existerar, dvs den behållare som passerade in har barnelement. Kom ihåg det nod
håller det passerade elementets första barnelement.
gör medan (node = node.nextSibling);
Steg 5 - Slingan väsentligen, väl loopar genom barnnoderna som slutar när slingan är vid den slutliga noden.
om (node.nodeType === 3)
Steg 6 - Det här är den intressanta delen. Vi får tillgång till nodetype
egenskapen [skrivskyddad] av noden för att avleda vilken typ av nod det är. Ett värde av 3 innebär att det är en textnod, så vi kan fortsätta. Om det gör livet enklare för dig kan du skriva om det som så: om (node.nodeType == Node.TEXT_NODE)
.
val = node.nodeValue; new_val = val.replace (sök, ersätt);
Steg 7 - Vi lagrar nuvarande värde för textnoden, först upp. Därefter ersätter vi snabbt förekomsten av sökordet med ersättning med den inhemska byta ut
JavaScript-metod. Resultaten lagras i variabeln new_val
.
om (new_val! == val)
Steg 8 - Fortsätt endast om värdet har ändrats!
om (! text_only && /Steg 9a - Kom ihåg det
text endast
parameter. Detta kommer in i spel här. Detta används för att ange huruvida behållaren ska behandlas som en som innehåller elementnoder inuti. Koden gör också en snabb intern kontroll för att se om den innehåller HTML-innehåll. Det gör det genom att leta efter en öppnings tagg i innehållet inew_val
.Om ja, sätts en textnod inför den nuvarande noden och nuvarande nod läggs till i
ta bort
array som ska hanteras senare.annars node.nodeValue = new_val;Steg 9b - Om det bara är text, injicera den nya texten direkt i noden utan att gå igenom DOM jonglering hoopla.
remove.length && $ (remove) .remove ();Steg 10 - Slutligen, när slingan är klar, tar vi snabbt bort de ackumulerade noderna från DOM. Anledningen till att vi gör det efter att slingan har slutförts är att avlägsnande av en nod i mitten kommer att skruva upp slingan själv.
Projekt
Det lilla projektet vi ska bygga idag är ganska grundläggande. Här är listan över våra krav:
Notera: Det här är mer ett bevis på koncept än vad du bara kan använda otrolig. För att förhindra att artikeln blir oförskämd har jag naturligtvis hoppat över ett antal sektioner som är av yttersta vikt för produktionsklar kod - valideringen till exempel.
Det faktiska fokuset här borde vara på själva plugin och de utvecklingsmetoder som den innehåller. Kom ihåg, det här är mer av en beta-demo för att visa något coolt som kan göras med det här pluginet. Rengör alltid och validera dina ingångar!
Dekonstruktion: jQuery replaceText Dekonstruktion: jQuery replaceText
av Siddharth för de underbara folket på Nettuts+Den här sidan använder den populära ersättnings-plugin-pluggen av Ben Alman. I denna demo använder vi den för att markera godtyckliga bitar av text på den här sidan. Fyll i ordet, letar du efter och slår gå.
<-- Assorted text here -->
HTML-filen ska vara ganska förklarande. Allt jag har gjort är att skapa en textinmatning, två länkar att tillämpa och ta bort höjdpunkten samt en paragraf som innehåller en mängd olika text.
kropp font-family: "Myriad Pro", "Lucida Grande", "Verdana", sans-serif; typsnittstorlek: 16px; p marginal: 20px 0 40px 0; h1 font-size: 36px; vaddering: 0; marginal: 7px 0; h2 font-size: 24px; #container width: 900px; marginal-vänster: auto; marginal-höger: auto; vaddering: 50px 0 0 0; position: relativ; #haiz padding: 20px; bakgrund: #EFEFEF; -moz-border-radius: 15px; -webkit-gräns-radie: 15px; gräns: 1px fast # C9C9C9; #search width: 600px; marginal: 40px auto; text-align: center; #keyword width: 150px; höjd: 30px; vaddering: 0 10px; gräns: 1px fast # C9C9C9; -moz-border-radius: 5px; -webkit-gräns-radie: 5px; bakgrund: # F0F0F0; typsnittstorlek: 18px; # apply-highlight, # remove-highlight padding-left: 40px; .highlight bakgrundsfärg: gul;
Återigen, ganska självförklarande och ganska grundläggande. Det enda som ska noteras är klassen kallad markera
som jag definierar. Detta kommer att tillämpas på texten som vi behöver markera.
På detta stadium ska din sida se ut så här:
Första beställningen av dagen är att snabbt koppla in vår länk med deras hanterare så att texten är markerad och obehindrat på lämpligt sätt.
var searchInput = $ ("# keyword"), searchTerm, searchRegex; $ ( "# Gälla-highlight") klickar du på (markera). $ ("# remove-highlight"). bind ("klicka", funktion () $ ("# haiz"). removeHighlight (););
Ska vara ganska enkelt. Jag förklarar några variabler för senare användning och bifogar länkarna till deras hanterare. markera
och removeHighlight
är extremt enkla funktioner vi ser nedan.
funktion highLight () searchTerm = searchInput.val (); searchRegex = ny RegExp (searchTerm, 'g'); $ ("# haiz *"). replaceText (searchRegex, "'+ SEARCH +'');
ReplaceText
plugin genom att passera i lämpliga värden. Jag väljer att direkt inkludera sökterm
i märkningen för korthet.jQuery.fn.removeHighlight = function () return this.find ("span.highlight"). varje (funktion () med this.parentNode replaceChild (this.firstChild, detta););
En snabb och smutsig, hacky metod för att få jobbet gjort. Och ja, det här är ett jQuery-plugin eftersom jag ville lösa in mig själv. Klassen är dock fortfarande hårdkodad.
Jag letar bara efter varje span tagg med en klass av markera
och ersätta hela noden med det värde som den innehåller.
Innan du får dina pitchforks redo, kom ihåg att det här är bara för demonstration. För din egen applikation behöver du en mycket mer sofistikerad unhighlight-metod.
Och vi är klara. Vi kollade på ett otroligt användbart plugin, gick igenom källkoden och slutligen avslutade genom att skapa ett mini-projekt med det.