JQuery - att lägga till element

Från Webbling
Hoppa till: navigering, sök
Den utskrivbara versionen stöds inte längre och kanske innehåller renderingsfel. Uppdatera din webbläsares bokmärken och använd standardutskriftsfunktionen istället.

När man skriver webbapplikationer vill man ofta lägga till och ta bort element dynamiskt. Man vill uppdatera utseendet och/eller vilken information som visas. jQuery har många olika kommandon som kan hjälpa till med detta. Vi ska gå igenom de mest användbara metoderna som finns till för att lägga till element.

append

Vi har redan sett ett par exempel där vi använt oss av metoden append. Vad denna metod gör är att den lägger till innehåll i slutet av element. Liksom de flesta jQuery-metoder som hanterar noder, så kan denna metod skapa nya element utifrån HTML-kod.

Lägga till ett nytt element

Vi tar ett exempel:

See the Pen ZQKMMK by Patrik Grip-Jansson (@PGJ) on CodePen.

I exemplet har vi en väldigt enkel HTML-struktur, där section:ens innehåll är det som är av intresse. I koden väljer vi ut sektionen och anropar append på denna. Eftersom vi har skickat med en text-sträng till append kommer denna att omvandlas till ett nytt element. Därefter läggs detta element till i DOM. Det placeras sist i section, eftersom vi använder append. Elementet kommer nu att ligga med i DOM:en, placerat som sista barnet under section. För webbläsaren är det ingen större skillnad på element som kommer ifrån den nedladdade HTML-koden eller de som vi lagt till dynamiskt i efterhand.

Alla element är likvärdiga

Vi lägger till lite mer kod i vårt exempel för att illustrera att DOM:en inte gör skillnad på var elementet kommer ifrån.

See the Pen pgPOQR by Patrik Grip-Jansson (@PGJ) on CodePen.

Efter att vi lagt till elementet, så har vi lite ny kod. Denna kod väljer ut alla p-element och ändrar deras innehåll. De element som redan fanns med ifrån början och vårt nytillagda element påverkas allesammans på samma vis av förändringen. Webbläsaren gör alltså ingen skillnad på hur elementen dök upp i DOM.

Att lägga till flera element samtidigt

Om man vill kan man skicka med flera inparametrar till append. Den kommer då att lägga till det som specificeras i parametrarna, en efter en. Ett exempel på det kan vara:

See the Pen wMdERa by Patrik Grip-Jansson (@PGJ) on CodePen.

Även här skapades nya element. Först två p-element, därefter ett h1-element. Det spelar alltså ingen roll vilken typ av element vi lägger till.

Att lägga till ett redan existerande element

Vi kan även lägga till element som redan är skapade. Då skickar vi med en referens till elementet istället för en sträng. Så här:

See the Pen wMdEOK by Patrik Grip-Jansson (@PGJ) on CodePen.

Vi letar först på ett element i DOM. Vi väljer det första p-elementet. Vi söker sedan ut section och säger åt jQuery att lägga till elementet sist i sektionen. Men vad händer nu? Jo, vårt första stycke förflyttades sist i sektionen. Elementet är ju kopplat till en position i DOM, men när vi kör append så skrivs elementets gamla position över av den nya positionen (något av en förenkling av vad som händer). Därmed förflyttas alltså elementet till slutet.

Man får inte detta förflyttningsproblem om man skickar in en sträng istället för ett element. I sträng-fallet, skapas ett nytt element för varje tilläggning. Så även om du kör en selektor som matchar flera element, så kommer det att skapas nya underelement för varje "tilläggning". Vi kör ett exempel på detta.

See the Pen BjRqdQ by Patrik Grip-Jansson (@PGJ) on CodePen.

När exempelkoden körs, så skapas alltså inte bara ett element ifrån strängen. Istället skapas ett nytt element för varje matchning som sker.

clone

Oftast vill vi inte att element ska förflyttas runt när man append:ar dem, såsom hände i föregående exempel. När vi läser ut ett element och sen lägger till det någon annanstans vill vi oftast göra en kopia av elementet och lägga till kopian på den nya positionen. Självklart har jQuery en lösning som möjliggör detta.

Kopior skapar man med metoden clone. Denna metod skapar en mer eller mindre exakt kopia av det angivna elementet. Vi ändrar vårt exempel till att använda clone.

See the Pen QyvVPK by Patrik Grip-Jansson (@PGJ) on CodePen.

Nu får vi kvar original p:n och vi får en ny kopia som läggs till i slutet av sektionen. Kopian har med sig samma HTML-attribut som originalet hade. Det som inte följer med är eventuella kopplingar till händelsehanterare som är angivna i element (vi återkommer till vad detta är). För att vara så snabbt och effektivt som möjligt tas inte dessa med default. Om man vill att även dessa ska hänga med i kopian, kan man ange true som inparameter till clone. Då hänger även kopplingen till händelsehanterarna med.

Att använda clone är ett bra sätt på vilket man kan hantera element som ska vara "mallar" till nya element. Man skapar ett mall-element, gör en kopia av det, lägger till kopian på rätt plats och därefter fyller man i kopians innehåll med den information man vill visa upp. På så vis kan man lätt skapa mallar som man har med i HTML-koden och därmed kan editera och titta på. Själva grundmallen kan man sedan dölja med t.ex. CSS, och sen sätta så att enbart kopiorna blir synliga. Det är en metod som vi kommer att använda oss av i senare exempel här på Webbling.

Man måste dock vara lite försiktig när man skapar kopior och ska använda dem som mallar. Det räcker t.ex. inte att köra clone en enda gång och sen använda den nya kopian gång på gång. Då händer ju samma sak som i ett tidigare exempel, dvs vi förflyttar kopian till olika ställen. Vi måste skapa nya kopior varje gång vi vill lägga till något som baseras på vår mall.

Ett annat problem som kan uppträda är följande:

See the Pen ZQKMNX by Patrik Grip-Jansson (@PGJ) on CodePen.

Av någon anledning fick vi tre stycken nya element i slutet av sektionen. Varför det? Jo, det är för att vi väljer ut de element som har klassen a. I första fallet finns ju bara ett i DOM. Men när vi lagt till en kopia, ja då finns det ju två element som matchar. Så vår nästa clone gör kopior på bägge dessa element. Vilket ju inte är vad vi ville i detta fall.

Att komma runt dupliceringsproblemet

Hur kan man då komma runt dupliceringsproblemet? Vi måste på något sätt se till att vår selektor får ett mer specifikt urval, så att enbart mallen väljs ut. Kanske provar man att sätta om så att mall-elementet har en ID istället, dessa ska ju vara unika. Men då kommer man att upptäcka att även ID:t kopieras, så vi får flera element med samma ID. Något som egentligen inte webbläsaren borde gilla, men de flesta webbläsare beter sig vara som om det vore en klass. Så det hjälper inte i detta fall. En bättre, och fungerande, lösning är att samla mallarna i en egen mall-sektion och välja ut dem baserat på var de ligger. Vi gör om vårt exempel:

See the Pen bEWmNe by Patrik Grip-Jansson (@PGJ) on CodePen.

Vi har nu skapat en div med ID mallar och placerat något som kan tjäna som mall inuti denna. För att visa hur man kan använda detta på "riktigt" så har vi även lagt till lite CSS som döljer mallarna. Vi vill ju antagligen att det enbart är kopiorna som syns. Som du ser löste denna version vårt problem.

Att ändra innehållet i en mall

När vi hanterar mallar, så är det ju oftast för att vi vill ha många element av samma sort, men vi vill ha olika innehåll i varje kopia. Detta gör vi enklast genom att ändra på innehållet innan vi lägger till det i DOM:en igen.

See the Pen bEWmVw by Patrik Grip-Jansson (@PGJ) on CodePen.

Vi kan köra den "vanliga" jQuery-metoderna på ett element även om detta ännu inte är tillagt i DOM. Så vi kan skapa en kopia, förändra den och så lägga ut resultatet i DOM. Ett lätt och smidigt sätt att hantera mallar.

Nu fick vi ju kod som var relativt likformig och vi bör förstås göra om det hela till en funktion och på så vis förenkla hanteringen av våra mallar. Vi ska titta på ett till exempel, där vi gjort lite mer omfattande mallar samt en funktion som hanterar dessa.

See the Pen JGNmGe by Patrik Grip-Jansson (@PGJ) on CodePen.

Titta igenom JavaScript-koden och se om du kan hänga med...

Som du kanske såg, så användes en ny funktion i ovanstående exempel, nämligen; .find(). Med hjälp av denna funktion kan man söka fram underelement inuti element. Så när vi skapat vår mall, kan vi använda .find() för att påverka underelement i mallen. Därmed kan vi sätta namn och liknande parametrar inuti vår mall på ett enkelt vis.

prepend

Om vi vill lägga till något till ett element och vill att det ska hamna först i elementet, då kan vi använda oss av prepend. Denna metod fungerar precis som append med den skillnaden att elementen läggs till först.

Vi modifierar ett av våra tidigare exempel och använder prepend istället för append.

See the Pen qbmJag by Patrik Grip-Jansson (@PGJ) on CodePen.

Vårt kopierade element hamnar först i sektionen, före alla element som redan fanns där. Om vi skulle köra prepend en gång till, skulle det nya elementet hamna överst. Varje nytt element gör att de gamla förflyttas ner i layouten.

Vårt prepend:ade element hamnar till och med före vår h1. Vilket kanske inte är vad vi egentligen vill, men det är vad vi beordrade jQuery att göra. Men om vi nu vill ha det efter h1, hur gör vi då? Den första lösning man tänker på kanske är att ändra selektorn till section h1. Detta kommer inte att fungera, då kommer vårt nya element att läggas till som första underelement inuti h1-elementet. Vilket det nog aldrig finns någon anledning till att vilja göra. Nej, vi behöver faktiskt en annan metod för att lösa detta på ett bra vis!

after

Med after kan vi lägga till ett element direkt efter ett annat (eller flera andra). Det hamnar alltså inte inuti det angivna elementet såsom varit fallet med append och prepend. Det blir istället att ligga som ett eget, fristående element direkt efter och på samma nivå som det angivna elementet.

Vi kör ett exempel.

See the Pen eJWPvr by Patrik Grip-Jansson (@PGJ) on CodePen.

Här löstes alltså problemet vi hade i förra sektionen. Genom att välja ut h1 och köra en .after() kunde vi få vår text att hamna direkt efter rubriken.

before

Föga överraskande så finns det en motsvarighet till after som lägger till element före andra element. Denna heter förstås before.

Vi kör ett exempel på detta:

See the Pen rxmqmr by Patrik Grip-Jansson (@PGJ) on CodePen.

Det finns väl inte mycket att säga om det exemplet...

Nästa aktivitet

Nu har vi tittat på olika versioner av hur vi kan lägga till element i DOM. I nästa sektion ska vi se hur man kan plocka bort dem.

jQuery - att ta bort element