Spotlight jQuery replaceText

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.


Ett ord från författaren

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.


Introducerar replaceText

Vi sparkar av saker genom att fokusera på Ben Almans utmärkta ersättnings-plugin. Här är några snabba info:

  • Typ: plugin
  • Teknologi: JavaScript [Byggd på jQuery-biblioteket]
  • Författare: Ben Alman
  • Fungera: Diskret, kortfattat sätt att ersätta textinnehåll

Problemet

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.


Lösningen

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 eller data 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.


Användande

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.


Dekonstruera källan

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 i new_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:

  • Primärt krav: Applicera en markeringseffekt på text som extraheras från användarinmatning. Detta bör tas om hand helt av plugin.
  • Sekundärt krav: Ta bort höjdpunkten i flygningen, efter behov. Vi trummar upp ett litet kodstycke för att hjälpa till med det här. Inte produktionsklar men ska göra ganska bra för våra syften.

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!


Stiftelsen: HTML och CSS

    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å.

Applicera highlightRemove highlight

<-- 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:


Samspelet: JavaScript

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 +''); 
  • Jag har valt att skapa en vaniljfunktion, och inte ett jQuery-plugin, eftersom jag är lat som en hög med klippor. Vi börjar med att fånga in rutan för inmatningsboxen.
  • Därefter skapar vi ett regelbundet uttrycksobjekt med sökordet.
  • Slutligen åberopar vi 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.


Avslutar

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.