30. april 2026

Gennemløbe DOM'en

DOM’en tillader os at gøre alt med dens elementer og deres indhold, men først skal vi “nå det” tilsvarende DOM-objekt.

Alle operationer på DOM’en starter med document-objektet. Det er “hoveddøren” til din DOM. Fra det kan vi tilgå enhver node.

Her er et billede af links, der tillader rejse mellem DOM-noder:

Lad os diskutere dem lidt i detaljer.

I toppen: documentElement og body

De øverste trænoder er tilgængelige direkte som document-egenskaber:

<html> = document.documentElement
Den øverste document node er document.documentElement. Det er DOM-noden for <html> tagget.
<body> = document.body
En anden meget brugt DOM-node er <body>-elementet – document.body.
<head> = document.head
Tagget <head> er tilgængeligt som document.head.
Der er en hage: document.body kan være null

Et script kan ikke tilgå et element, der ikke eksisterer ved det øjeblik, hvor scriptet kører.

I særdeleshed, hvis et script er indeni <head>, så er document.body ikke tilgængeligt, fordi browseren har endnu ikke læst det.

Så, i eksemplet nedenfor viser den første alert null:

<html>

<head>
  <script>
    alert( "Fra HEAD: " + document.body ); // null, der er ikke noget <body> endnu
  </script>
</head>

<body>

  <script>
    alert( "Fra BODY: " + document.body ); // HTMLBodyElement, findes nu
  </script>

</body>
</html>
På DOM sprog betyder null at det “ikke eksisterer”

Hvis du møder null i DOM’en, betyder det “eksisterer ikke” eller “ingen sådan node”.

Children: childNodes, firstChild, lastChild

Der er to termer vi vil bruge fra nu af:

  • Child nodes (eller children/børn) – elementer der er direkte børn af et element. For eksempel er <head> og <body> børn af <html> elementet.
  • Descendants (eller efterkommere) – alle elementer der er indlejret i et givent element, inklusivt deres bør og børn af børn osv.

For eksempelt har <body> her <div> og <ul> som børn (og nogle tomme tekstnoder):

<html>
<body>
  <div>Start</div>

  <ul>
    <li>
      <b>Information</b>
    </li>
  </ul>
</body>
</html>

… og efterkommere af <body> er ikke kun børnene <div>, <ul> men også elementer der ligger dybere indlejret, såsom <li> (barn af <ul>) og <b> (et barn af <li>) – hele den del af træet.

Samlingen childNodes lister alle child nodes, inklusiv tekstnoder.

Eksemplet nedenfor viser børn af document.body:

<html>
<body>
  <div>Start</div>

  <ul>
    <li>Information</li>
  </ul>

  <div>Slut</div>

  <script>
    for (let i = 0; i < document.body.childNodes.length; i++) {
      alert( document.body.childNodes[i] ); // Text, DIV, Text, UL, ..., SCRIPT
    }
  </script>
  ...mere her...
</body>
</html>

Bemærk en interessant detalje her. Hvis vi kører eksemplet ovenfor, er det sidste element vist <script>. Faktisk har dokumentet mere indhold nedenfor, men på det tidspunkt hvor scriptet kører har browseren ikke læst det endnu, så scriptet ser det ikke.

Egenskaberne firstChild og lastChild giver hurtig adgang til første og sidste barn.

De er bare hurtige genveje. Hvis der findes børn, så er det altid sandt:

elem.childNodes[0] === elem.firstChild
elem.childNodes[elem.childNodes.length - 1] === elem.lastChild

Der er også en særlig funktion elem.hasChildNodes() til at tjekke om der er nogle børn.

DOM samlinger

Som vi kan se så ligner childNodes et array. Men det er faktisk ikke et array, men en collection (samling) – et særligt array-lignende objekt.

Det har derfor to vigtige konsekvenser for os:

  1. Vi kan bruge for..of til at iterere over den:
for (let node of document.body.childNodes) {
  alert(node); // viser alle noder fra samlingen
}

Det er fordi den er itererbar (leverer egenskaben Symbol.iterator, som det kræves).

  1. Array metode virker ikke fordi det ikke er et array:
alert(document.body.childNodes.filter); // undefined (der er ikke nogen filter-metode!)

Det første er skønt. Det andet er håndterbart, fordi vi kan bruge Array.from til at skabe en “rigtig” array fra samlingen, hvis vi vil have array-metoder:

alert( Array.from(document.body.childNodes).filter ); // function
DOM samlinger er kun til at læse fra

DOM samlinger, eller i det hele taget – alle egenskaber til navigation som vi taler om i dette kapitel er kun til at læse fra.

Vi kan ikke erstatte et barn med noget andet ved at tildele childNodes[i] = ....

At ændre DOM kræver andre metoder. Vi vil se dem i næste kapitel.

DOM samlinger er live

Næsten alle DOM samlinger, med enkelte undtagelser, er live. Med andre ord, de afspejler den nuværende tilstand af din DOM.

Hvis vi holder en reference til elem.childNodes, og tilføjer/fjerner noder til DOM, så vises de automatisk i samlingen.

Brug ikke for..in til at loope over samlinger

Samlinger er itererbare ved brug af for..of. Nogle gange prøver folk at bruge for..in til det.

Lad være med det. Et for..in-loop itererer over alle enumerable egenskaber. Og samlinger har nogle “ekstra” sjældent brugte egenskaber, som vi normalt ikke vil have:

<body>
<script>
  // viser 0, 1, length, item, values and more.
  for (let prop in document.body.childNodes) alert(prop);
</script>
</body>

Søskende og forældre (siblings og parents)

Siblings er noder som er børn af samme forælder.

For eksempel så er <head> og <body> søskende her:

<html>
  <head>...</head><body>...</body>
</html>
  • <body> bliver kaldt den “næste” eller “højre” søskende af <head>,
  • <head> bliver kaldt den “forrige” eller “venstre” søskende af <body>.