JQuery - element-samlingar
Hitintills har vi använt jQuery genom att haka på metoder direkt efter en sökning i DOM. Metoderna har då förändrat de utvalda elementen direkt. Faktum är att man även kan lagra undan de element som sökts ut i en variabel, så att man kan jobba mer dynamiskt med dessa.
Läs ut och lagra ett element
I grunden är det mycket enkelt att spara undan resultatet ifrån en DOM-sökning. Det är bara att tilldela sökningen direkt till en variabel. Så här kan det se ut:
Variabeln $styckeC
kommer att innehålla ett objekt som har en referens som pekar på det utvalda elementet. Denna kan vi sedan använda för att utföra diverse jQuery-metoder. Följande två metoder är alltså likvärdiga:
Med den stora skillnaden att vi kan använda $styckeC
gång på gång utan att behöva göra en ny sökning i DOM. Vilket är mycket mer effektivt än att söka gång på gång.
Lagring och återanvändning ger prestanda
Faktum är att det ofta är en bra idé att leta reda på behövliga element i början av koden, för att sedan lagra undan dem i en variabel. Då kan man komma åt dem när man behöver, utan att behöva göra en ny sökning. Sökningarna kan vara relativt kostsamma och det är bra att undvika att utföra dem i onödan. Detta går förstås inte att göra om det du ska leta fram är helt dynamiskt och förändras hela tiden. Men oftast söker man ju fram element som i sig själv är statiska. Även om man ändrar innehållet i de lagrade elementen, så förändras inte "var" själva elementen återfinns.
Namngivning
Du kanske märkte att variabeln vi jobbade med hade ett lite speciellt namn. Vi inledde dess namn med ett "$
". Det är relativt vanligt att namnge variabler vars innehåll kommer ifrån en jQuery sökning på detta vis.
Att läsa ut flera element
I föregående exempel tittade vi på hur man kunde läsa ut ett specifikt element ifrån DOM. Vad händer om vår sökning matchar flera element? Det blir faktiskt ingen större skillnad. Istället för att få ett enda värde, får vi en samling element (ungefär som en array). Faktum är att även när vi tog ut ett enda element, så fick vi tillbaka en samling. Det var bara det att den samlingen enbart innehöll ett enda element.
Vi kan alltså göra som följer:
Här skapas en samling av element som innehåller de resultat som erhålls när vi matchar alla element av typen p
. När vi utför metoder med hjälp av denna variabel kommer alla element som ingår i samlingen att påverkas. Återigen sker detta utan att vi behöver skriva någon loop.
jQuery skapades för länge sen. Då saknades stöd för det mesta i webbläsarna. Det gör att vissa lösningar som jQuery bygger på inte är helt optimala i dagens förhållanden. För att kunna hålla reda på en samling av element så var man tvungen att "bädda" in denna i en egen, jQuery-specifik datastruktur. När man söker ut element utan att använda jQuery och använder webbläsarens inbyggda DOM-API får man tillbaka en annan typ av datastruktur - en NodeList (faktum är att man kan få andra typer av datastrukturer också).
jQuerys datastruktur och NodeList är inte kompatibla. De innehåller bägge olika egenskaper samt olika metoder. Detta gör att det kan vara lite besvärligt om man blandar jQuery-kod och vanilla-kod. Det går alltid att omvandla ifrån den ena datastrukturen till den andra.
Man får se till att hålla reda på vilken typ som lagrats i en variabel. Ett sätt man kan underlätta detta är genom att använda en namngivningskonvention som indikerar vad en variabel har för innehåll. Vanligtvis namnger man därför variabler som innehåller jQuerys element-variant med ett "$
" i början av variabelnamnet, t.ex; $allStycken = $("p");
Samlingar och each()
I vissa fall vill vi gå igenom varje element var för sig. Vi kanske inte vill att alla element i samlingen ska påverkas på samma sätt. Då kan vi skapa en explicit loop med hjälp av jQuerys each
-metod. Den fungerar så här:
I exemplet söker vi först fram en samling element. Sedan utför vi en each
-loop över dessa. Som inparameter tar each
en funktion. Denna funktion utförs en gång för varje element som finns med i samlingen.
Funktionen man skickar med i each
kan ta två inparameterar:
- Den första talar om vilket element i ordningen som hanteras och den börjar räkna ifrån
0
. - Den andra är det DOM-element som finns på den positionen i samlingen. Lägg märke till att detta inte är en jQuery-element, utan ett "vanligt" DOM-element. Det gör att vi måste konvertera det till jQuery-varianten om vi vill använda jQuery-metoder på det. Det gör man med;
$( element )
, vilket skapar en jQuery-element.
Eftersom element
-variabeln inte är ett rent jQuery-element, så valde vi att att namnge variabeln, utan ett inledande "$
"-tecken.
Eftersom vi lägger till ett löpnummer i varje elements innehåll, så skulle ovanstående exemplet inte gått att genomföra utan att köra en loop som går igenom varje element.
Egentligen behöver man inte ha med den andra parametern i den funktion som each
kallar på. Varje gång som loopen körs, sätts this
till att vara kopplad till det element som ska behandlas. Även detta är ett "normal" element och inte ett jQuery-element. Vi hade alltså kunnat skriva ovanstående exempel på detta vis.
Skillnaden är, som du ser, rätt så minimal. Möjligen är den första varianten att föredra, då det är lättare att se exakt vad det är man utför sina operationer på. Om du tittar runt på lite olika jQuery-exempel kommer du att se att bägge varianterna förekommer i ungefär lika stor utsträckning. Välj den du gillar bäst. Ha dock i åtanke att det går att göra på flera vis, så att du inte blir förvånad när du läser någon annans kod.
Omvandling med $()
Som vi såg kunde $()
inte bara användas för att utföra sökningar i DOM. I föregående exempel omvandlade den ett "normal" element till motsvarande jQuery-variant. Den kan även användas för att omvandla HTML-kod till ett element. Ett exempel på detta:
$()
"märker" att detta är HTML-kod och skapar ett element utifrån detta.
Många av de jQuery-metoder som hanterar element skapar nya element om de märker att deras inparametrar är HTML-kod. Detta kan vara mycket användbart och vi kommer att se mer av detta i nästa aktivitet.