Översikt
Nu är det dags att programmera mot ett av webbläsarens äldsta, men samtidigt viktigaste, API:er: DOM, Document Object Model. Veckans tre artiklar går igenom hur du hittar i dokumentets träd, hur du ändrar i det och hur du skriver HTML som mallar i stället för att bygga den element för element. Information om veckans upplägg annonseras löpande i kursens Zulip-kanal.
Veckostart med DOM och HTML-templates
Section titled “Veckostart med DOM och HTML-templates”Tisdagen i kursvecka 9 började med frågor om den muntliga examinationen av A3. Därefter gick Mats
och Mikael igenom veckans tre artiklar om DOM-trädet, levande samlingar och HTML templates, och
Daniel informerade om valet av studentrepresentant. Passet avslutades med Mikaels exempelprogram
Pixeldex, där samma sida byggs först med createElement och sedan med en mall.
Om passet
Section titled “Om passet”Tisdagens pass i kursvecka 9 hölls av Mats och Mikael tillsammans. Det inleddes med frågor från
chatten om den muntliga examinationen av A3. Därefter gick Mats igenom veckans tre artiklar om DOM,
med Mikael som bollplank. Efter en dryg kvart bröt Daniel in med information om valet av
studentrepresentant. Passets andra halva ägnades åt Mikaels exempelprogram Pixeldex, där han
läste och ändrade DOM:en i konsolen och sedan visade hur samma sida kan byggas med createElement
och med en HTML-mall.
Den muntliga examinationen av A3
Section titled “Den muntliga examinationen av A3”Får du ha boken eller anteckningar framme? Ja. Vid den muntliga examinationen får du ha vilka hjälpmedel du vill, så länge du inte ringer en vän eller har någon bredvid dig. Mats vill att examinationen ska likna den arbetssituation du så småningom hamnar i, där det är en styrka att snabbt kunna hitta den information du behöver. Men examinationen är begränsad till en halvtimme. Kan du inte stoffet finns det inte tid att slå upp allt, och hinner ni inte igenom examinationen blir du underkänd. Du behöver inte kunna varenda detalj, men du behöver kunna det här.
Mikael fyller i att det är viktigare att kunna resonera än att kunna ett exakt svar. Fastnar du kan du berätta hur du tänker, och det ger den du pratar med mycket förståelse. Från lärarstolen ser han examinationen mer som ett samtal än som ett förhör. Uppgiften för examinatorn är att ta reda på om du når kursens mål, och i vilken grad. A3 betygssätts med U, G eller VG.
Lämnas A3 in på samma sätt som A2? Ja: du löser uppgiften, skapar en merge request och fyller i reflektionsdokumentet. Skillnaden är att du därefter också bokar en tid för den muntliga examinationen. Deadline är tisdag 3 november kl. 17.00, och förhören hålls torsdag 5 och fredag 6 november. Mats lägger ut tiderna på kursens Moodle-webbplats på fredagen, ibland så sent som på måndagen, så är du klar tidigare får du vänta tills tiderna är publicerade. Tiderna har Mats eller Mikaels namn, men det säger inget om vem du faktiskt möter. Du kan inte välja examinator, det sköter Mats när han skapar protokollen.
En fråga i chatten var om examinationen bara handlar om A2 och A3. Mikael svarade i chatten med uppgiftsbeskrivningen: förhöret täcker delkurs A, kursvecka 1–7, alltså den rena JavaScript-delen, inget om webbläsaren eller DOM.
Veckans artiklar: DOM-trädet
Section titled “Veckans artiklar: DOM-trädet”Allt i kursvecka 9 handlar om DOM:en, och allt leder fram till nästa veckas webbkomponenter. För att
alls kunna arbeta i webbläsaren måste du veta hur du ändrar saker där, och de sakerna är, lite
slarvigt uttryckt, HTML. Den första artikeln, DOM-trädet, går igenom hur sidan är organiserad som
ett träd av noder. Elementen tänker du kanske på automatiskt, men det finns också kommentarer och
textnoder. Mats lyfter särskilt att vita tecken räknas: radbrytningen och mellanslagen direkt efter
<article> i artikelns exempel blir en egen textnod före <h1>. Har du inte koll på det blir det
svårt att orientera sig i trädet.
Mikael kommer från serversidan. Sedan början av 90-talet har han mest renderat HTML på servern, med till exempel PHP, så det här är inte hans hemmaplan. Ändå är det grundkunskap: du måste förstå hur webbläsaren bygger trädet från HTML-sidan och kunna navigera i det, till exempel i fliken Elements i utvecklingsverktygen.
Webbläsarkriget. Historiskt har just DOM:en varit en stor stötesten. Under webbläsarkriget runt sekelskiftet tolkade Microsoft standarderna på sitt eget sätt i Internet Explorer, som hade en mycket stor del av marknaden. Du fick skriva specialkod beroende på vilken webbläsare besökaren använde. Mikael minns också striden mellan HTML och XHTML, och att det var med HTML5 och JavaScript-standarden från 2015 som det kändes som att webben hittade en bra väg framåt.
Välja ut element. Mikael använder getElementById när han har ett id, vilket han ofta har,
annars querySelector, och sällan querySelectorAll. Mats använder i kursen nästan uteslutande
querySelector och querySelectorAll. Selektorsyntaxen kom in i standarden efter att jQuery hade
visat hur enkelt det kunde vara, och använder du jQuery bara för att välja ut element kan du lika
gärna använda standarden. Mats tror dock inte att jQuery är så dött som Mikael antyder. Mikael
undervisade själv i jQuery 2012 och ser biblioteken som idésprutor: de löser ett behov, och är
idéerna bra nog hamnar de förr eller senare i standarden. Med CSS-selektorer kan du också filtrera
direkt, som i artikelns document.querySelectorAll('img:not([alt])'), i stället för att samla in
alla bilder och loopa igenom dem för att hitta dem som saknar alt.
Samlingar är inte arrayer. Många av metoderna returnerar en NodeList eller en
HTMLCollection, inte en array. Mikael försöker att inte dyka ner i detaljerna, men Mats tycker
att det räcker långt att komma ihåg en sak: får du ett konstigt felmeddelande när du kör map på
en samling ska den göras om till en riktig array, med Array.from() eller spridningsoperatorn.
Levande och statiska samlingar. Beroende på hur du hämtar elementen får du en levande eller en
statisk samling. getElementsByClassName returnerar en levande samling, querySelectorAll en
statisk ögonblicksbild. Artikelns fråga om fyra <li class="todo"> visar varför det spelar roll:
loopen som tar bort klassen hoppar över vartannat element, så två har kvar klassen. Mikael
konstaterar att Mats alltid svarar fel på sådana frågor, och Mats medger att han också gör det.
Poängen är att ha i bakhuvudet att det finns levande och statiska samlingar, annars blir buggen
jobbig att hitta.
Spretig namngivning. Mats stör sig på namnen: alla noder får du med childNodes, bara
elementen med children (inte childElements), noderna med firstChild och lastChild (inte
firstChildNode) och elementen med firstElementChild. Ibland finns node eller element med i
namnet, ibland inte. Det sätter sig när du arbetar med det. Mikael påminner om att API:et har sina
rötter i webbläsarnas barndom i mitten av 90-talet, och tipsar om att använda konsolen för att
inspektera vad som finns i varje nod.
Mats råd är att läsa artiklarna flera gånger, gärna vid olika tillfällen. Första gången bildar du dig en uppfattning om vad det handlar om, utan att försöka lägga detaljer på minnet. Det är svårt att minnas detaljer innan du har ett träd att hänga upp dem i.
Att ändra i DOM:en och HTML templates
Section titled “Att ändra i DOM:en och HTML templates”Den andra artikeln, Att ändra i DOM:en, speglar hur det ser ut 2026. Det finns väldigt mycket
äldre kod där ute som du behöver förstå, men ny kod ska skrivas på ett modernt sätt. Ett exempel är
den klassiska appendChild, där du i ny kod hellre använder append. Mats har försökt uppdatera
alla övningsuppgifter och exempel så att de följer de senaste arbetssätten.
Den tredje artikeln, HTML templates, börjar med ett exempel som bygger upp HTML med
createElement, setAttribute, textContent och så vidare. Mikael ser en vägg av text som han
bara scrollar förbi. Med <template> skriver du i stället HTML som vanlig HTML, och det blir
betydligt lättare att både skriva och underhålla när strukturen växer. Mikael påpekar att det inte
är något fel på DOM-API:et, det är så JavaScript pratar med DOM:en, men en mall är ett litet lager
ovanpå som gör vissa saker enklare.
Mats uppmaning: glöm inte bort templates. Det är inte ovanligt att studenterna i den sista examinationsuppgiften, där du väljer lösning helt fritt, hamnar i artikelns första exempel. Då får han kommentera varför du har glömt bort mallarna. HTML templates är också en av de standarder som webbkomponenter är hopsatta av, så det finns ingen enskild standard som heter webbkomponenter.
Mikael ser vägen framför sig: DOM-trädet, hur du ändrar i det, mallar, sedan webbkomponenter, och för många så småningom ett ramverk med JSX. Allt för att göra det lättare att bygga klientapplikationer. Mats tror att det landar i en komponentbaserad arkitektur, och de kommande veckorna handlar om hur komponenter kommunicerar med varandra och ändå förblir löst kopplade. I grunden är webbkomponenter inget annat än att på ett eller annat sätt manipulera DOM-strukturen.
Övningsuppgiften. Tiny Tunes sträcker sig över kursvecka 9 och 10 och har nio steg. Den här veckan gör du steg 1–7, som speglar de tre artiklarna. Steg 8 och 9 handlar om webbkomponenter och hör till nästa vecka.
Information från Daniel: välj studentrepresentant
Section titled “Information från Daniel: välj studentrepresentant”Daniel bröt in för att informera om att det är dags att välja studentrepresentant, om ni inte redan har gjort det. Studentrepresentanten företräder sin årskurs i programmet Webbprogrammerare i programrådet. Det finns en representant för ettan, en för tvåan och en för trean. Tidigare fanns en för distans och en för campus, men numera är det en för hela årskursen. Representanten är någon du kan vända dig till om det finns problem, till exempel med en kursansvarig.
Uppdraget är demokratiskt valt, och Daniel tror att det ger ersättning för de möten man deltar i. Programrådet träffas i november och går igenom hur det går för de olika årskullarna och för programmet, lyfter frågor som behöver lyftas och försöker förbättra utbildningen för alla. Det är studenterna själva som ansvarar för valet. Er Discord-server kan vara en plats för det, och behövs det kan handledarna hjälpa till med hur det går till. Daniel informerar också campusstudenterna och återkommer om när programrådet hålls.
Daniel har också skapat Zulip-kanalen #Webbprogrammerare - Programmet, där han lägger information som gäller programmet som helhet, som avslutningar eller problem som behöver nå alla studenter. Följ den, och posta inget skräp där, eftersom många kommer att läsa den.
Pixeldex: läsa och ändra DOM:en
Section titled “Pixeldex: läsa och ändra DOM:en”Mikael har för sin egen skull byggt ett exempelprogram för att leka med det artiklarna tar upp:
Pixeldex med DOM och HTML template,
en liten “Pokédex-light” med kort för egenritade varelser i en <ul id="pokedex">. Repot är tänkt
att forkas och följa i fem steg: läsa DOM:en i konsolen, ändra den i konsolen, samma sak i
JavaScript, en mall i konsolen och till sist mallen i JavaScript. Startläget ligger i public/, med
npm run dev, och facit för steg 3–5 i solution/ (npm run steg3, steg4 och steg5).
Läsa. I konsolen hämtade Mikael document.title, sidans <ul id="pokedex"> och kortens delar,
och konstaterade hur hjälpsam konsolen är när du expanderar det du får ut. Mats framhåller
utvecklingsverktygen som en central del: de finns i alla webbläsare av en anledning. Får du en
referens till ett element har du ett objekt, och då kan du börja ändra på saker. Mikael tyckte för
länge sedan att det var roligt att gå igenom en sidas element och få den att falla sönder. Mats
berättar att det inte är helt ovanligt att han under en muntlig examination börjar flytta runt
div-element på sidan, till studentens förvåning.
Ändra. Mikaels vanligaste ändring av en främmande sida: när han har glömt ett lösenord ändrar
han fältets type från password till text i utvecklingsverktygen för att se det ifyllda
lösenordet. I exemplet växlade han i stället en CSS-klass på ett kort, något han gör ofta och som
är förvånansvärt användbart. Med JavaScript, HTML och CSS tillsammans får du dynamiska effekter. Sedan
byggde han ett nytt kort bit för bit: ett li-element, en h3 för namnet, och li.append(name)
för att koppla ihop dem. Alla delar måste byggas upp en och en, och det finns ingen genväg om du
väljer det sättet. Mats ser det som ett sätt att pröva bilden du har i huvudet mot verkligheten.
Pixeldex: från createElement till mall
Section titled “Pixeldex: från createElement till mall”Steg 3: ren JavaScript. Mikael körde facit för steg 3, där knappen Fånga en ny! lägger till
ett kort och Släpp tar bort ett. Koden hämtar knappen, räknaren och listan med querySelector,
har varelserna som ännu inte är fångade i en array, uppdaterar räknaren och bygger varje kort i en
funktion createCard med en lång rad createElement, classList.add och append. Bakom en
dynamisk sida finns alltid funktioner som tar ett nytt värde och anropar DOM-API:et, det finns
ingen snabbare genväg.
Tror Mats att koden kan bli kortare? Det finns sätt att minska antalet rader, svarar han diplomatiskt, om Mikael klarar det är en annan sak. Koden fungerar, och det ska alltid prioriteras först. Men Mats skulle inte vilja underhålla den, till exempel om varje kort ska få ett extra element. När du har en lösning kan du fundera på om den kan göras bättre, så att den är lättare att skriva och framför allt att underhålla. Om tio år ska någon våga ändra i den. Samtidigt ska du undvika att överdesigna och ta till släggan för ett litet problem. Du behöver kunna hela skalan.
Steg 4: mallen i konsolen. I steg 4 ligger en <template id="creature-template"> i
index.html. Den renderas inte, och längst ner på sidan syns inget spår av den, men i Elements
finns den med sitt innehåll i ett #document-fragment. I konsolen klonade Mikael mallens innehåll
med template.content.cloneNode(true), fyllde i namn, typ och HP och lade in fragmentet i listan.
Han kände sig mer bekväm med det här, det kändes mer produktionsmässigt. Mats håller med: ska korten
förändras är det mycket enklare att ändra i mallen, som är ren HTML, än att hitta rätt bland alla
createElement och append.
Hur mycket används <template> i verkligheten? Det har Mats inte undersökt. Men i utbildningens
kurser används det för lite där det hade passat. I ramverk som Angular, React och Vue finns andra
konstruktioner, men förstår du hur mallar fungerar enligt standarden står du väl rustad, eftersom
de fungerar på motsvarande sätt oavsett ramverk.
Mikael frågade också om mallen kan ligga i en egen fil, som han läst om i Mats artiklar. Det tas upp
i avsnittet Mallen i en egen fil i artikeln HTML templates: det finns ännu inget standardiserat
sätt, men i kursen löser Vite det med ?raw.
Steg 5: mallen i JavaScript. Mikael sade att han hoppade till steg 4, men det var facit för steg
5 han visade. Där har de statiska korten tagits bort ur index.html, och hela listans innehåll,
även de tre första varelserna, byggs från en array i JavaScript med createCard, som nu klonar
mallen och fyller i den. Skillnaden syns när du jämför: i Elements ligger korten i listan, men i
View Page Source är <ul id="pokedex"> tom. Sidkällan visar det webbläsaren hämtade, Elements
hur DOM-trädet ser ut när skriptet har kört.
Mikael ser det som ett skifte i tänkandet, från statiska HTML-sidor med allt innehåll till sidor där innehållet byggs upp från JavaScript. I dag ligger datan i sidan, men om några veckor kanske den hämtas från en webbtjänst via ett REST-API. Principen är densamma: hämta data, rendera innehåll och uppdatera små delar. Mats rekommenderar starkt att arbeta igenom exemplet, och Mikael funderar på att låta det växa in i nästa veckas webbkomponenter, så att ni kan jämföra varianterna och välja den ni tycker är snyggast.
$0 i konsolen
Section titled “$0 i konsolen”Mats frågade om Mikael brukar använda $0. Det hade han aldrig gjort, och tänkte bara på jQuery.
Markerar du ett element i Elements och skriver $0 i konsolen får du en referens till det
markerade elementet, utan att behöva skriva en querySelector. Mikael hade alltid suddat bort
== $0 som står bredvid det markerade elementet utan att fundera på vad det betyder. Det sparar
tid vid felsökning, till exempel när du har satt en brytpunkt i en metod.
Mats använder också konsolen för omvänd ingenjörskonst: vad behöver jag skriva för att komma åt just det här elementet? Mikael provskriver ofta en avancerad selektor i konsolen innan han för in den i koden, eftersom det går snabbare än att ladda om och testa.
Inför torsdagen
Section titled “Inför torsdagen”Ett bra avstamp för veckan är att arbeta med Mikaels exempel, sedan övningsuppgiften Tiny Tunes och därefter utmaningarna. Övningen är uppdelad i nio steg över två veckor, så behöver du koppla av från A3 kan du göra ett eller två steg och undersöka hur DOM-trädet fungerar.
Exemplet, Pixeldex med DOM och HTML template,
kan du forka och följa själv. Där läser och ändrar du DOM:en i konsolen och bygger sedan samma sida
med createElement och med en <template>, i fem steg med facit.
Torsdag med Tiny Tunes
Section titled “Torsdag med Tiny Tunes”Torsdagen i kursvecka 9 började med frågor om A3: deadline, återkoppling på A2 och hur den muntliga
examinationen går till. Därefter livekodade Mikael i övningsuppgiften Tiny Tunes, från steg 1 till en
fri lek med bilder, cloneNode och ett filter för stegen, som Mats kommenterade. Passet avslutades
med två av veckans utmaningar om element och noder.
Om passet
Section titled “Om passet”Torsdagens pass i kursvecka 9 hölls av Mats och Mikael tillsammans. Den första kvarten handlade om
A3: deadline, återkoppling på A2 och hur den muntliga examinationen går till. Därefter funderade de
över om <template> kan lösa ett vardagsproblem, gemensam sidhuvud- och sidfotskod på en statisk
webbplats. Större delen av passet livekodade Mikael i veckans övningsuppgift Tiny Tunes. Han gjorde
steg 1 och lekte sedan fritt vidare, och Mats kommenterade koden i efterhand. Passet avslutades med
två av veckans utmaningar och en A3-fråga från chatten.
A3: deadline och den muntliga examinationen
Section titled “A3: deadline och den muntliga examinationen”I schemat står det nu uttryckligen att deadline för A3 är hård. Mats skrev dit det eftersom frågan ofta kommer: lämnar du inte in i tid hänvisas du till omexaminationen längre ner i schemat. Hittar du en liten bugg i det du har lämnat in är det okej att rätta den, men att committa hälften av koden efter deadline är det inte. Mikael har slutat vara “mesig” med deadlines och har en egen text om varför han inte skjuter upp dem.
Senast vid deadline ska du ha gjort en merge request och bokat en tid för den muntliga examinationen på kursens Moodle-webbplats. Tiderna läggs ut tidigast fredag och senast måndag.
Återkoppling på A2. Återkopplingen kommer i din merge request, och ofta också som mejl om du har en e-postadress registrerad i GitLab. Har du lämnat in men inte fått återkoppling kan något ha gått snett, till exempel fel milstolpe eller fel etiketter. Skicka då ett meddelande via individuell handledning på Zulip med en länk till din merge request. En student som frågade i chatten fanns inte med i Mats listor, och det reds ut där i stället för under passet.
Ska du ta bort din merge request när du har fått återkoppling? Nej. Det är Mats och Mikael som stänger eller mergar dem, och bara de kan göra det. Ligger en fortfarande öppen har de missat den, och det är deras ansvar att städa. Mats går igenom dem ungefär en gång i månaden.
Hur lång är den muntliga examinationen? 30 minuter, i två delar: en frågesport och ett samtal om koden du har lämnat in, där du visar att du äger den. Mikael räknar med 10 minuter frågor, 10 minuter kod och 10 minuter om något krånglar, vilket det gör med jämna mellanrum. För de flesta är det också första gången ni pratar med varandra, så en del går åt till socialt snack.
Det är normalt att vara nervös. Mikael vet att en fråga som ser konstig ut kan göra att du blir alldeles blank. Mats påpekar skillnaden mot en skriftlig tenta: på ett papper står det inget mer än frågan, men i ett samtal kan examinatorn ställa ledande frågor och hjälpa dig förbi spärren. Hans erfarenhet är att de flesta går därifrån med en positiv känsla. Mikael ser förhöret som träning i en skyddad verkstad inför situationer där du utsätts för press på riktigt i arbetslivet.
Under förhöret hinner ni inte gå igenom varje sats. Ni diskuterar vissa delar av koden: hur de fungerar och vad som hade hänt om du hade gjort på ett annat sätt. Mats bästa förberedelse är att göra examinationsuppgiften, och det räcker. Mikael brukar “fylla sitt primärminne” före en föreläsning, och skulle på samma sätt gå igenom sin kod, särskilt de svåraste delarna, och öva på att navigera i alla filer. Mats bror pluggade i flera dagar och gick sedan på bio kvällen före tentan. Hur du gör är individuellt, men det handlar inte om att läsa boken från pärm till pärm. Du ska ha lärt dig sakerna genom att skriva och köra koden, och har du kämpat dig igenom A3 står du tillräckligt stadigt för förhöret.
Kan en mall ersätta kopierad sidhuvud- och sidfotskod?
Section titled “Kan en mall ersätta kopierad sidhuvud- och sidfotskod?”Mikael har inte använt <template> särskilt mycket, men gillar elementet. Han tänkte på webbplatsen
ni byggde i HTML och CSS tidigare i programmet. Där kopierar du sidhuvud och sidfot till varje ny
sida, glömmer sedan att uppdatera någon av dem och blir frustrerad. Kunde en mall lösa det?
Allt går att göra med ettor och nollor, svarar Mats, frågan är om det är det bästa alternativet. Med 3 sidor är kopiering bökigt, med 30 ohållbart. Med en mall skriver du koden en gång, klonar den och sätter in den på rätt ställe i varje sida, och då behöver du bara underhålla mallen. Samma idé finns när sidor renderas på servern. Mikael kommer därifrån: han renderade sina sidor med PHP eller JSP, och då var det inget problem att sätta ihop sidhuvud, sidfot och innehåll. Med bara HTML, CSS och lite JavaScript är det lurigare.
Mats frågade sin AI-assistent och fick först förslag om Astro, eftersom kursens webbplats är byggd
med Starlight, som bygger på Astro, ett verktyg för att generera statiska webbplatser. Där delas
sidhuvud och sidfot mellan alla sidor. Utan Astro föreslog assistenten webbkomponenter, och utan dem
partiella HTML-sidor som läses in med JavaScript. Då behöver du fetch, som kursen inte har kommit
till än. Det går att ordna, men det intressanta är tanken. Webbkomponenter är kanske det egentliga
svaret.
Mikael tycker att det är bra att prova nya saker i olika sammanhang för att bygga upp en bild i huvudet. Ber någon honom bygga en webbplats ställer han först 17 kontrollfrågor, och när han vet vilken sorts webbplats det är vet han ungefär vilket verktyg och vilken teknik som passar. Men först behövs grunderna. Med det ni kan i dag handlar lösningen om att lägga till element på en viss plats i DOM-trädet, och det är precis vad Tiny Tunes övar.
Tiny Tunes, steg 1: en textnod
Section titled “Tiny Tunes, steg 1: en textnod”Mikael hade forkat och klonat Tiny Tunes, veckans enda övningsuppgift. Steg 1–7 hör till den här veckan och steg 8–9, om webbkomponenter, till nästa. Mikael noterade att övningen saknar enhetstester. Det är medvetet, svarar Mats: de flesta övningar har tester i dag, men det är värdefullt att också öva manuell testning, eftersom det är vad du gör i de flesta examinationsuppgifterna.
All kod skrivs i src/js/index.js. Steg 1 lyder: skapa en textnod med texten “Hello World!” och
lägg den i stycket med id step01-hello. Mikael hämtade stycket med
document.querySelector('#step01-hello'), skapade en textnod med document.createTextNode() och
lade in den med append. Han skrev ut båda i konsolen och såg att stycket gick att markera på sidan
men inte textnoden, som ännu inte fanns i DOM-trädet.
Det finns minst sju sätt att sätta in noden, och Mikael undrade om han hade valt ett som Mats
godkänner. Mats var nyfiken på något annat: kan append skapa textnoden åt dig? Mikael skickade in
en vanlig sträng, Mats eget testord “Hejhopp”, och resultatet blev detsamma, en textnod på rätt
plats. Det står i artikeln Att ändra i DOM:en:
till skillnad från den äldre appendChild tar append emot strängar och gör dem till textnoder.
Steget ber dig ändå uttryckligen skapa en textnod, så att du lär dig createTextNode.
Mikael tipsade också om alias i terminalen. Programmerare är lata, så han har korta alias för git pull och för att gå upp i katalogstrukturen, där två, tre eller fyra punkter hoppar upp lika många
nivåer. Tipset från tisdagens sammanfattning om att byta standardterminal hade han sett, men han
tror inte att han kommer att använda det.
Fri lek: bilder, stil och var noderna hamnar
Section titled “Fri lek: bilder, stil och var noderna hamnar”Efter steg 1 började Mikael “frikoda” och kom aldrig längre i övningen. Men leken berörde flera av de kommande stegen.
En bild. Det finns ingen createImageNode. En bild är ett eget element, så Mikael skapade ett
img med document.createElement('img'), satte src och alt, och lade till det i stycket. Bilden
blev väldigt stor. Han försökte med width-attributet och satte sedan bredden via style. Steg 5 i
övningen handlar om just bilder, och där ska du inte glömma alt-texten.
En p i en p. Sedan skapade han ett nytt stycke med createElement('p'), gav det text med
textContent och lade in det med append. I Elements syntes plötsligt en p inuti en p, och
Mikael blev osäker på om det ens är tillåtet. Han provade prepend, som också lägger noden inuti
elementet, och sedan before och after, som lägger den bredvid elementet, som ett syskon.
Samma nod flyttas. Mikael hade anropat prepend, before och after med samma p. Ändå fanns
stycket bara på ett ställe, efter. Mats frågade varför, och Mikael kom fram till det själv: det är
samma nod hela tiden. Sätter du in en nod som redan finns i trädet flyttas den, och ingen kopia
skapas. De tre första raderna gjorde i praktiken ingenting.
cloneNode och argumentet true. För att få ett stycke både före och efter skapade Mikael en
kopia med p.cloneNode(). Kopian blev ett tomt stycke. Mats förklaring: utan argument är det samma
som cloneNode(false), som bara kopierar noden själv och inte dess barn. Med cloneNode(true)
följde texten med. Mikael hade tidigare gjort samma sak på ett annat sätt: han klonade textnoden, som
inte har några barn, och då räcker en grund kopia. Ett p med en textnod i är däremot ett litet
träd, och då behövs en djup kopia. Det tomma elementet i Elements var ledtråden. Mats framhåller
att true är oerhört centralt, inte minst i webbkomponenter med template.content.cloneNode(true).
Se avsnittet Kopiera noder.
Lärdomen enligt Mats: ha koll både på hur sidan ser ut i webbläsaren och på hur strukturen ser ut i DOM-trädet. Saknas ett element där du väntar dig det finns det inte längre på det stället i trädet, och du förstår snabbare att du behöver klona, och klona djupt.
Alla rubriker. Mikael skriver sällan själv querySelectorAll, men valde ut sidans alla h2 och
loopade igenom dem. Han måste alltid slå upp vilken loop han ska använda. För varje rubrik lade han
till text med prepend och en sträng, och prepend gör också strängar till textnoder. Steg 3 i
övningen bygger på samma sak.
Ett filter för stegen
Section titled “Ett filter för stegen”Till sist ville Mikael skriva kod som du faktiskt skriver i en klient: ett filter som visar vissa
saker och döljer andra, som när du filtrerar en tabell eller lista. Med nio steg på samma sida skulle
det också bli rörigt för honom, så han skapade ett input-fält, lade det överst med prepend, satte
bredden till 200 pixlar och valde ut alla steg med en CSS-selektor för de div-element som ligger
direkt under body. En händelselyssnare läser fältets värde varje gång det ändras, bygger ett id som
step01 med en template-sträng och visar bara det steget. Det fungerade, men de horisontella
linjerna mellan stegen ligger utanför div-elementen och visades fortfarande. Mikael gissade att
något med syskonelement skulle lösa det, men där tog tiden slut.
Mikael poängterar kopplingen mellan HTML, CSS och JavaScript: alla stegens id följer samma mönster,
och en bra struktur i HTML ger mycket enklare kod. Mats valde step01, step02 och så vidare i
stället för step1, så att ett tionde steg inte skulle ställa till det. Mikael påminner om citatet
från några veckor sedan om att datastrukturerna avslöjar om koden är snygg, och här är HTML och CSS
lite av datastrukturerna.
Händelsestyrd programmering tas upp längre fram, men Mats lyfter att det är ett annorlunda sätt att tänka. Koden i lyssnaren körs inte när sidan laddas, utan först när användaren ändrar innehållet i fältet. Upplever du det som lurigt är det för att det är det.
Mats kommentarer om koden:
- Kan du CSS sparar du kod. Selektorn för
div-elementen direkt underbodyvisar att samma kunskap fungerar iquerySelectorochquerySelectorAll. Hade Mikael bara skrivitdivhade han fått alladiv-element på sidan. Ibland behöver du mer, men har du koll på CSS blir livet som klientsideprogrammerare mycket enklare. - Ta bort lyssnare efter dig. Lyssnaren fungerar, men en lyssnare du lägger till bör du också ta bort. Förr hette skälet Internet Explorer och dess minnesläckor. Moderna webbläsare städar bättre, men det är enklast att alltid göra det. Det tas upp i kursvecka 11, se Händelser i webbkomponenter.
- Utseende hör hemma i CSS. Bredden på fältet sattes via
stylei JavaScript. En interaktionsdesigner som vill ändra den blir inte glad över att behöva pilla i JavaScript-koden. I en kort demonstration är det okej, men annars lägger du stilen i en CSS-regel och sätter klassen från koden: separation of concerns. Se avsnittet Stil direkt från JavaScript, som också visar egenskapenhiddenför att dölja och visa element. - En blivande webbkomponent. Fältet med sina inställningar är en klockren webbkomponent, men bara koden som skapar och konfigurerar fältet. Koden som väljer ut stegen hör inte dit, eftersom en webbkomponent inte ska veta något om dokumentet den ligger i.
Utmaningarna 09-03 och 09-04
Section titled “Utmaningarna 09-03 och 09-04”Mats tror att utmaningarna känns abstrakta om du inte har gjort övningsuppgifterna först. De är i stor utsträckning gjorda för att väcka diskussion, och varken Mats eller Mikael skulle ha rätt på allt. Mikael fick prova två av frågorna. Tips: under kugghjulet uppe till höger kan du dölja sidofältet för att få mer plats.
09-03: Hur många element innehåller kodsnutten? Mikael räknade p och a, och sedan textnoder
och vita tecken, och stannade på fyra. Rätt svar är två. Mats kallade det overengineering: frågan
gäller element, och textnoder är något annat. Begreppen avgränsar problemet, och därför är det så
viktigt att använda dem rätt.
09-04: Hur många noder innehåller kodsnutten? Mats tips: alla element är noder, men alla noder är
inte element. Mikael svarade fem. Rätt svar är sex: p-elementet, textnoden med radbrytning och
indentering före a, a-elementet, textnoden Foo, textnoden med radbrytningen före </p> och
textnoden med radbrytningen efter </p>. Mikael glömde den sista.
Poängen med de två frågorna är skillnaden mellan element och noder. Beroende på vilket anrop du använder mot DOM-trädet pratar du med elementen eller med noderna, och resultatet kan bli mycket olika. När koden inte beter sig som du väntar dig kan det bero på att du har valt en metod för noder när du ville ha element, eller tvärtom. Mikael understryker att grundförståelsen gör felsökningen mycket lättare. Arbetar du igenom övningarna och utmaningarna står du väl rustad inför webbkomponenterna, och utmaningarna är inte heller fel att titta på inför förhöret nästa vecka.
A3: flera ess på handen
Section titled “A3: flera ess på handen”En fråga från chatten: esset är värt 1 eller 14 beroende på vad som är mest fördelaktigt för handen. Får algoritmen värdera ett ess till 14 och ett annat till 1 på samma hand, så att två ess blir 15? Ja, svarade Mats. Att ett ess räknas som 1 eller 14 betyder inte att nästa ess måste räknas på samma sätt. Du går igenom handen ess för ess. Mikael tycker att den delen av koden är rolig, eftersom du kan fundera extra på hur du väljer att skriva den. Det går att uttrycka på många sätt, men det viktigaste är att det fungerar.
Veckans artiklar
Section titled “Veckans artiklar”Veckans teori finns samlad i tre artiklar. Läs dem i ordning; varje artikel bygger på den föregående.
-
DOM-trädet – vad DOM är, skillnaden mellan noder och element, hur du väljer ut element och hur du rör dig i trädet.
-
Att ändra i DOM:en – hur du skapar, flyttar och tar bort noder, sätter text på ett säkert sätt och arbetar med attribut, klasser och stil.
-
HTML templates – varför HTML ska skrivas som HTML och hur
<template>-elementet förbereder dig för nästa veckas webbkomponenter.
Läsanvisningar
Section titled “Läsanvisningar”Under läsanvisningar hittar du veckans kapitel som ska läsas i kurslitteraturen. Planera upp och dela upp läsningen under veckan.
Övningar
Section titled “Övningar”Under Övningsuppgifter hittar du övningsuppgifter som det är lämpligt att du arbetar med under veckan.
Äldre inspelningar
Section titled “Äldre inspelningar”Inspelningen från 2020 tar upp samma stoff som artiklarna, men är delvis inaktuell och har en presentation på engelska. Artiklarna räcker, men vill du se genomgången i rörlig bild finns den kvar här. Sammanfattning och presentation till inspelningen hittar du i samlingen av inspelningar för delkurs B.
HTML Elements and the Document Object Model – DOM-API:et, att välja ut, skapa och ändra noder samt HTML templates. Motsvarar alla tre artiklarna.
Handledning
Section titled “Handledning”Skicka gärna in frågor på förhand via formuläret som du når här:
Examinationsuppgift A3
Section titled “Examinationsuppgift A3”Nu bör du verkligen vara igång och arbeta med examinationsuppgiften. Kanske bör du faktiskt ha som mål att färdigställa denna under denna kursvecka.
Läs mer om “Examinationsuppgift A3 - Tjugoett” här
Utmaningar
Section titled “Utmaningar”Under Utmaningar hittar du tio frågor om noder och element, hur du väljer ut och skapar element, klasser och HTML templates, ett bra sätt att stämma av att du har förstått artiklarna.
Studiefrågor
Section titled “Studiefrågor”Här är ett antal frågor som du kan försöka besvara och diskutera tillsammans med din AI-assistent. Tveka inte att lyfta någon av frågorna till handledningen för att fortsätta diskussionen med lärare och studiekamrater.
- Ge en kort förklaring av vad DOM är och hur det hänger ihop med HTML-koden jag skriver. Vad är skillnaden mellan en nod och ett element?
- Varför ger
firstChildibland en textnod när jag förväntar mig ett element? Visa ett exempel och hur jag undviker det. - Vad är skillnaden mellan en
NodeListoch enHTMLCollection, och mellan en levande och en statisk samling? Ge mig ett exempel där skillnaden ger en bugg. - Jag vill lägga till en
ul-lista med fem punkter från JavaScript. Visa två sätt, ett medcreateElementoch ett med en<template>, och låt mig avgöra vilket som är lättast att läsa. - Varför är
innerHTMLriskabelt när innehållet kommer från en användare? Visa ett exempel på en attack och hurtextContentstoppar den. - Vad är skillnaden mellan att sätta en klass med
classNameoch medclassList.add()? När bör jag sätta stil direkt viastylei stället för att byta klass? - Förklara vad HTML templates är och hur de förhåller sig till webbkomponenter.
Här följer tips till hur du kan prioritera bland kursmaterialet för att komma igång med veckan.
- Det viktiga är att slutföra A3. Vänta inte in i det sista. Satsa på att göra din MR redan nu på fredag så har du extra tid, om det behövs.
- Försök prioritera så du också hinner läsa veckans tre artiklar. Du behöver inte komma ihåg varje metodnamn, men ta dig extra tid med den sista artikeln om HTML templates, som nästa vecka bygger vidare på. Inspelningen är frivillig.
- När du läst artiklarna så finns det en övningsuppgift på nivån Uppvärmning, Tiny Tunes, där du får möjlighet att testa att programmera mot DOM:en och med HTML templates i webbläsaren. Gör steg 1–7 den här veckan; steg 8–9 hör till nästa veckas webbkomponenter.
