4. maj 2026
Dette materiale er kun tilgængeligt på følgende sprog: عربي, English, Español, Français, Indonesia, Italiano, 日本語, 한국어, Русский, Türkçe, Українська, Oʻzbek, 简体中文. Hjælp os med at oversætte til Dansk.

Node egenskaber: type, tag og contents

Lad os gå lidt mere i dybden med DOM-noder.

I dette kapitel vil vi se mere på, hvad de er, og lære deres mest brugte egenskaber.

DOM node klasser

Forskellige DOM-noder kan have forskellige egenskaber. For eksempel har et element svarende til et <a> tag, link-relaterede egenskaber, og den svarende til et <input> tag har input-relaterede egenskaber osv. Tekst-noder er ikke de samme som element-noder. Men der er også fælles egenskaber og metoder mellem dem alle, fordi alle klasser af DOM-noder danner en enkelt hierarki.

Hver DOM-node tilhører den tilsvarende indbyggede klasse.

Roden af hierarkiet er EventTarget, som er nedarvet fra Node, og andre DOM-noder nedarver fra den.

Her er først en oversigt over klasserne, og derefter vil vi se på dem i detaljer:

Klasserne er:

  • EventTarget – er roden. En “abstract” klasse for alt andet.

    Objekter af denne klasse bliver aldrig oprettet. Den fungerer som en base så alle DOM-noder understøtter hændelser (såkaldte “events”), som vi vil studere senere.

  • Node – er også en “abstract” klasse, der fungerer som en base for DOM-noder.

    Den tilbyder den grundlæggende træ-funktionalitet: parentNode, nextSibling, childNodes og så videre (de er getters). Objekter af Node-klassen bliver aldrig oprettet. Men der er andre klasser, der nedarver fra den (og derigennem nedarver Node-funktionaliteten).

  • Document, af historiske grunde ofte nedarvet af HTMLDocument (selvom den nyeste specifikation ikke dikterer det) – refererer til dokumentet som et hele.

    Det globale objekt document tilhører præcis denne klasse. Det fungerer som et indgangspunkt til DOM.

  • CharacterData – en “abstract” klasse, nedarves af:

    • Text – klassen der korresponderer med en tekst indeni elementer, f.eks. Hej i <p>Hej</p>.
    • Comment – klassen for kommentarer. De vises ikke, men hver kommentar bliver et medlem af DOM.
  • Element – er den grundlæggende klasse for DOM-elementer.

    Den tilbyder element-niveau navigation som nextElementSibling, children og søgemetoder som getElementsByTagName, querySelector.

    En browser understøtter ikke kun HTML. Den understøtter også ting som XML and SVG. Så Element klassen fungerer som base for mere specifikke klasser: SVGElement, XMLElement (vi bruger dem ikke i denne sammenhæng) og HTMLElement.

  • Endelig er HTMLElement den grundlæggende klasse for alle HTML-elementer. Vi vil arbejde med den det meste af tiden.

    Den bliver nedarvet af konkrete HTML-elementer, som har deres egne klasser, for eksempel:

Der er mange andre tags med deres egne klasser, der kan have specifikke egenskaber og metoder, mens nogle elementer, såsom <span>, <section>, <article> ikke har nogen specifikke egenskaber, så de er instanser af HTMLElement-klassen.

Således kommer det fulde sæt af egenskaber og metoder for en given node som resultatet af arvekæden.

For eksempel, lad os betragte DOM-objektet for et <input> element. Det tilhører HTMLInputElement klassen.

Den får sine egenskaber og metoder som en superposition af (opstillet i arveorden):

  • HTMLInputElement – denne klasse leverer input-specifikke egenskaber,
  • HTMLElement – den leverer fælles HTML-elementmetoder (og getters/setters),
  • Element – den leverer generiske elementmetoder,
  • Node – den leverer fælles DOM-nodeegenskaber,
  • EventTarget – den giver støtte for hændelser (til dækning),
  • …og endelig nedarver den fra Object, så “almene objektmetoder” som hasOwnProperty også er tilgængelige.

For at se DOM-nodens klasse navn, kan vi huske på, at et objekt normalt har constructor egenskaben. Den refererer til klasse constructor, og constructor.name er dens navn. Så for document.body kan vi se:

alert( document.body.constructor.name ); // HTMLBodyElement

… eller vi kan bare bruge toString på den:

alert( document.body ); // [object HTMLBodyElement]

Vi kan også bruge instanceof for at tjekke nedarvning:

alert( document.body instanceof HTMLBodyElement ); // true
alert( document.body instanceof HTMLElement ); // true
alert( document.body instanceof Element ); // true
alert( document.body instanceof Node ); // true
alert( document.body instanceof EventTarget ); // true

Som vi kan se er DOM-noder regulære JavaScript-objekter. De bruger prototype-baserede klasser til arv.

Det kan også nemt vises ved at outputte et element med console.dir(elem) i en browser. Her kan du i konsollen se HTMLElement.prototype, Element.prototype og så videre.

console.dir(elem) versus console.log(elem)

De fleste browsere understøtter to udviklerrværktøjer: console.log og console.dir. De outputter deres argumenter til konsollen. For JavaScript-objekter er disse kommandoer normalt ens.

Men for DOM-elementer er de forskellige:

  • console.log(elem) viser elementets DOM-træ.
  • console.dir(elem) viser elementet som et DOM-objekt, godt til at udforske dets egenskaber.

Prøv det på document.body.

IDL i specifikationen

I specifikationen beskrives DOM-klasser ikke ved hjælp af JavaScript, men ved hjælp af et specielt Interface description language (IDL), som er nemmere at forstå.

I IDL er alle egenskaber foranstillet med deres typer. For eksempel, DOMString, boolean og så videre.

Her er et uddrag fra specifikationen med kommentarer, der forklarer IDL-syntaksen:

// Define HTMLInputElement
// Kolon ":" betyder at HTMLInputElement nedarver fra HTMLElement
interface HTMLInputElement: HTMLElement {
  // here go properties and methods of <input> elements

  // "DOMString" betyder at værdien af en egenskab er en streng
  attribute DOMString accept;
  attribute DOMString alt;
  attribute DOMString autocomplete;
  attribute DOMString value;

  // boolesk værdi i egenskab (true/false)
  attribute boolean autofocus;
  ...
  // nNu til metoderne: "void" betyder at metoden ikke returnerer nogen værdi
  void select();
  ...
}

Egenskaben “nodeType”

Egenskaben nodeType leverer en anden mere “gammeldags” måde at få datatypen af en DOM-node på.

Den har en numerisk værdi:

  • elem.nodeType == 1 for elementnoder,
  • elem.nodeType == 3 for tekstnoder,
  • elem.nodeType == 9 for dokumentobjektet,
  • der er et par andre værdier i specifikationen.

For eksempel:

<body>
  <script>
  let elem = document.body;

  // Lad os undersøge: hvilken datatype er noden elem?
  alert(elem.nodeType); // 1 => element

  // og dens første barn er...
  alert(elem.firstChild.nodeType); // 3 => text

  // for selve dokumentet er typen 9
  alert( document.nodeType ); // 9
  </script>
</body>

I moderne scripts kan vi bruge instanceof og andre class-baserede tests til at se nodetype, men nogle gange kan nodeType være enklere. Vi kan kun læse nodeType, ikke ændre det.

Tag: nodeName og tagName

Med en givet DOM-node kan vi læse dets tag-navn fra nodeName eller tagName egenskaber:

For eksempel:

alert( document.body.nodeName ); // BODY
alert( document.body.tagName ); // BODY

Er der nogen forskel mellem tagName og nodeName?

Det er der, men forskellen er reflekteret i deres navne, og foskellen er subtil.

  • Egenskaben tagName eksisterer kun for Element noder.
  • Egenskaben nodeName er defineret for alle noder via nedarvning fra Node:
    • for elementer betyder det det samme som tagName.
    • for andre typer af noder (text, comment, etc.) har det en streng med nodens type.

Med andre ord, tagName er kun understøttet af elementnoder (da det stammer fra Element-klassen), mens nodeName kan sige noget om andre nodetyper.

For eksempel, lad os sammenligne tagName og nodeName for document og en kommentarnode:

<body><!-- comment -->

  <script>
    // for comment
    alert( document.body.firstChild.tagName ); // undefined (ikke et element)
    alert( document.body.firstChild.nodeName ); // #comment

    // for document
    alert( document.tagName ); // undefined (ikke et element)
    alert( document.nodeName ); // #document
  </script>
</body>

Hvis vi kun arbejder med elementer, kan vi både bruge tagName og nodeName – der er ingen forskel.

Navnet på tag er altid i store bogstaver på nær i XML tilstand

Browseren har to tilstande den kan processere dokumenter: HTML og XML. Normalt bruges HTML tilstanden for websider. XML tilstanden aktiveres når browseren modtager et XML dokument med headeren: Content-Type: application/xml+xhtml.

I HTML tilstand skrives tagName/nodeName altid med store bogstaver: det er BODY enten for <body> eller <BoDy>.

I XML tilstand bevares små bogstaver “som de er”. I dag er XML tilstanden sjældent brugt.

innerHTML: indholdet

Egenskaben innerHTML tillader at trække HTML ud af et andet element som en streng.

Vi kan også ændre det, så det er en af de mest kraftige måder at ændre siden på.

Eksemplet viser indholdet af document.body og erstatter det derefter helt:

<body>
  <p>Et afsnit</p>
  <div>En div</div>

  <script>
    alert( document.body.innerHTML ); // slet det nuværende indhold
    document.body.innerHTML = 'Den nye BODY!'; // erstat det
  </script>

</body>

Vi kan prøve at indsætte ugyldigt HTML, så vil browseren fikse vores fejl og indsætte det korrekt i DOM’en. For eksempel, hvis vi glemmer at lukke en tag, så vil browseren gøre det for os:

<body>

  <script>
    document.body.innerHTML = '<b>test'; // glemt at lukke tag
    alert( document.body.innerHTML ); // <b>test</b> (fikset)
  </script>

</body>
Scripts eksekveres ikke

Hvis innerHTML indsætter et <script> tag i dokumentet bliver det en del af HTML, men eksekveres ikke.

Pas på: “innerHTML+=” overskriver fuldstændigt

Vi kan tilføje HTML til et element ved at bruge elem.innerHTML+="mere html".

Sådan her:

chatDiv.innerHTML += "<div>Hej<img src='smile.gif'/> !</div>";
chatDiv.innerHTML += "Hvordan går det?";

Men vi skal være meget forsigtige med at gøre dette. Det der foregår er nemlig ikke en tilføjelse, men en fuld overskrivning.

Teknisk set er disse to linjer det samme:

elem.innerHTML += "...";
// er en kortere måde at skrive:
elem.innerHTML = elem.innerHTML + "..."

Med andre ord gør innerHTML+= dette:

  1. Det gamle indhold er fjernet.
  2. Det nye innerHTML er skrevet i stedet (en sammenkædning af det gamle og det nye).

Da indholdet er “nulstillet” og genoprettet fra bunden, vil alle billeder og andre ressourcer blive genindlæst.

I eksemplet med chatDiv ovenfor genskaber linjen chatDiv.innerHTML+="Hvordan går det?" indholdet og henter smile.gif igen (forhåbentlig er det cached). Hvis chatDiv har en del anden tekst og billeder bliver genindlæsningen meget tydelig.

There are other side-effects as well. For instance, if the existing text was selected with the mouse, then most browsers will remove the selection upn rewriting innerHTML. And if there was an <input> with a text entered by the visitor, then the text will be removed. And so on.

Heldigvis er der andre måder at tilføje HTML end innerHTML, som vi snart vil se nærmere på.

outerHTML: fuld HTML af et elementof the element

Egenskaben outerHTML indeholder elementets fulde HTML. Det er det samme som innerHTML men inklusiv elementet selv.

Her er et eksempel:

<div id="elem">Hej <b>verden</b></div>

<script>
  alert(elem.outerHTML); // <div id="elem">Hej <b>verden</b></div>
</script>

Pas på: Modsat innerHTML, ændrer outerHTML ikke elementet. I stedet erstatter det det i DOM’en.

Ja, det lyder underligt, og det er det også. Derfor lige denne seperate note. Lad os se på det.

Forestil dig dette eksempel:

<div>Hej, verden!</div>

<script>
  let div = document.querySelector('div');

  // erstat div.outerHTML med <p>...</p>
  div.outerHTML = '<p>Et nyt element</p>'; // (*)

  // Wow! 'div' er stadig det samme!
  alert(div.outerHTML); // <div>Hej, verden!</div> (**)
</script>

Det er underligt, ikke?

I linjen med (*) erstattede vi div med <p>Et nyt element</p>. I det ydre dokument (DOM’en) kan vi se det nye indhold i stedet for den gamle <div>. Men, som vi kan se i linjen med (**) har værdien af den gamle div ikke ændret sig! Tildelingen af outerHTML ændrer ikke selve DOM-elementet (det objekt, som variablen ‘div’ i dette tilfælde refererer til), men fjerner det fra DOM’en og indsætter det nye HTML i dets sted.

Så, hvad der sker div.outerHTML=... er:

  • div blev fjernet fra dokumentet.
  • Et nyt stykke HTML <p>Et nyt element</p> blev indsat i dets sted.
  • div har stadig den gamle værdi. Det nye HTML blev ikke gemt i nogen variabel.

Det er så nemt at lave en fejl her: Ændr div.outerHTML og arbejd bagefter videre med div som om det indeholder det nye indhold. Men det gør det ikke. Det vil være korrekt for innerHTML, men ikke for outerHTML.

Vi kan skrive til elem.outerHTML, men skal huske, at det ikke ændrer det element, vi skriver til (‘elem’). Det indsætter det nye HTML i stedet. Vi kan få referencer til de nye elementer ved at forespørge på DOM’en.

nodeValue/data: tekst noders indhold

Egenskaben innerHTML er kun gyldig for element noder.

Andre node typer, såsom tekst noder, har deres modstykke: nodeValue og data egenskaber. Disse to er praktisk taget de næsten de samme, der er kun små specifikationsforskelle. Så vi vil bruge data, fordi det er kortere.

Her er et eksempel på læsning af indholdet fra en tekstnode og en kommentarnode:

<body>
  Hej
  <!-- Kommentar -->
  <script>
    let text = document.body.firstChild;
    alert(text.data); // Hej

    let comment = text.nextSibling;
    alert(comment.data); // Kommentar
  </script>
</body>

Vi kan forestille os grunde til at læse eller ændre dem, men hvorfor kommentarer?

Nogle gange indlejrer udviklere information eller template instruktioner til HTML brug i dem, i stil med:

<!-- if isAdmin -->
  <div>Velkommen, administrator!</div>
<!-- /if -->

… så kan JavaScript læse det fra data egenskaben og behandle de indlejrede instruktioner.

textContent: ren tekst

Egenskaben textContent leverer adgang til selve teksten inde i elementet: kun tekst – minus alle <tags>.

For eksempel:

<div id="news">
  <h1>Overskrift!</h1>
  <p>Marsboere angriber folk!</p>
</div>

<script>
  // Overskrift!
  // Marsboere angriber folk!
  alert(news.textContent);
</script>

Som vi kan se returneres kun teksten. Det er som om alle <tags> var klippet ud, men teksten i dem har fået lov til at blive.

I praksis er læsning af teksten på denne måde ikke så tit brugt.

Skrivning til textContent er meget mere nyttig, fordi det tillader os at skrive tekst på den “sikre måde”.

Lad os sige, vi har en vilkårlig streng, for eksempel indtastet af en bruger, og vi vil vise den på siden.

  • Med innerHTML bliver det sat ind “som HTML”, med alle HTML tags.
  • Med textContent bliver det sat ind “som tekst”, og alle symboler behandles bogstaveligt.

Compare the two:

<div id="elem1"></div>
<div id="elem2"></div>

<script>
  let name = prompt("Hvad er dit navn?", "<b>Peter-Plys!</b>");

  elem1.innerHTML = name;
  elem2.textContent = name;
</script>
  1. The first <div> gets the name “as HTML”: all tags become tags, so we see the bold name.
  2. The second <div> gets the name “as text”, so we literally see <b>Peter-Plys!</b>.

I de fleste tilfælde forventer vi tekst fra en bruger og vil behandle den som tekst. Vi vil ikke have uventet HTML ind på vores side. En tildeling via textContent sikrer præcis dette.

Den skjulte egenskab “hidden”

Egenskaben hidden og den tilsvarende HTML-attribute specificerer om elementet er synligt eller ikke.

Vi kan bruge den i HTML eller tildele den ved hjælp af JavaScript, sådan:

<div>Begge divs nedenfor er skjulte</div>

<div hidden>Med attributten "hidden"</div>

<div id="elem">JavaScript tildelte egenskaben "hidden"</div>

<script>
  elem.hidden = true;
</script>

Teksnisk set virker hidden på samme måde som style="display:none". men er kortere at skrive.

Her er et blinkende element:

<div id="elem">Et blinkende element</div>

<script>
  setInterval(() => elem.hidden = !elem.hidden, 1000);
</script>

Flere egenskaber

DOM elementer har flere egenskaber. Særligt findes egenskaber der afhænger af klassen. For eksempel:

  • value – værdien for tags som <input>, <select> og <textarea> (HTMLInputElement, HTMLSelectElement…).
  • href – hyperlink referencen “href” for <a href="..."> (HTMLAnchorElement).
  • id – værdien af “id” attributten, for alle elementer (HTMLElement).
  • …og meget mere…

For eksempel:

<input type="text" id="elem" value="value">

<script>
  alert(elem.type); // "text"
  alert(elem.id); // "elem"
  alert(elem.value); // value
</script>

De fleste standard HTML attributter har en tilsvarende DOM egenskab og vi kan umiddelbart tilgå dem som sådan.

Hvis vi vil kende til hele listen af understøttede egenskaber kan vi finde dem i specifikationen. For eksempel er HTMLInputElement dokumenteret på https://html.spec.whatwg.org/#htmlinputelement.

Eller, hvis vi vil have dem hurtigt eller er interesseret i en bestemt browser specifikation – kan vi altid outputte elementet ved hjælp af console.dir(elem) og læse egenskaberne. Eller udforske “DOM egenskaber” i Elements fanebladet i browserens udviklerværktøjer.

Opsummering

Hver DOM node tilhører en bestemt klasse. Klasserne udgør en hierarki. Den fulde sæt af egenskaber og metoder kommer som resultatet af nedarvning.

Vigtige DOM node egenskaber er:

nodeType
Vi kan bruge den til at se om en node er en tekst- eller elementnode. Den har en numerisk værdi: 1 for elementer,3 for tekstnoder, og et par andre for andre nodetyper. Kun læsning.
nodeName/tagName
For elementer. Viser tag navn (skrevet med store bogstaver med mindre browseren er i XML-mode). For ikke-elementnoder nodeName beskriver hvad det er. Kun læsning.
innerHTML
Indholdet af HTML for elementet. Kan ændres.
outerHTML
Det fulde HTML for elementet. Skrivning til elem.outerHTML berører ikke elem selv. I stedet bliver det erstattet med det nye HTML i den ydre kontekst.
nodeValue/data
Indholdet af en ikke-element node (tekst, kommentar). Disse to er næsten de samme, og vi bruger normalt data. Kan ændres.
textContent
Den tekst, der er inde i elementet: HTML minus alle <tags>. Skrivning til textContent sætter teksten ind i elementet, med alle specielle tegn og tags behandlet præcis som tekst. Kan dermed sikkert indsætte tekst fra brugere og beskytte mod uønsket indsættelse af HTML.
hidden
Når sat til true, gør det det samme som CSS display:none.

DOM noder har også andre egenskaber afhængigt af deres klasse. For eksempel, <input> elementet (HTMLInputElement) understøtter value, type, mens <a> elementet (HTMLAnchorElement) understøtter href etc. De fleste standard HTML attributter har en tilsvarende DOM egenskab.

Men, HTML attributter og DOM egenskaber er ikke altid de samme, som vi vil se i næste kapitel.

Opgaver

vigtighed: 5

Der er en træstruktur af indlejrede ul/li.

Skriv den kode der for hvert <li> viser:

  1. Hvad er teksten inde i det (uden undertræet)
  2. Antallet af indlejrede <li> – alle efterkommere, inklusiv de dybt indlejrede.

Demo i nyt vindue

Åbn en sandbox til opgaven.

Lad os lave en løkke over <li>:

for (let li of document.querySelectorAll('li')) {
  ...
}

I løkken skal vi hente teksten inde i hvert li.

Vi kan læse teksten fra det første barn af li, som er tekst node:

for (let li of document.querySelectorAll('li')) {
  let title = li.firstChild.data;

  // title er teksten inde i <li> før andre noder
}

Derefter kan vi hente nummeret af efterkommere med li.getElementsByTagName('li').length.

Åbn løsningen i en sandbox.

vigtighed: 5

Hvad viser scriptet nedenfor?

<html>

<body>
  <script>
    alert(document.body.lastChild.nodeType);
  </script>
</body>

</html>

Der er en lille hage er.

På det tidspunkt hvor <script> eksekveres er DOM noden præcis <script>, fordi browseren ikke har processeret resten af siden endnu.

Så resultatet er 1 (element node).

<html>

<body>
  <script>
    alert(document.body.lastChild.nodeType);
  </script>
</body>

</html>
vigtighed: 3

Hvad viser denne kode?

<script>
  let body = document.body;

  body.innerHTML = "<!--" + body.tagName + "-->";

  alert( body.firstChild.data ); // hvad er der her?
</script>

Svaret er: BODY.

<script>
  let body = document.body;

  body.innerHTML = "<!--" + body.tagName + "-->";

  alert( body.firstChild.data ); // BODY
</script>

Hvad sker der trin for trin:

  1. Indholdet af <body> erstattes af en kommentar. Kommentaren er <!--BODY-->, fordi body.tagName == "BODY". Som vi husker, er tagName altid versaler i HTML.
  2. Kommentaren er nu det eneste barn, så vi får den med body.firstChild.
  3. data-egenskaben af kommentaren er dens indhold (inde i <!--...-->): "BODY".
vigtighed: 4

Hvilken klasse hører document til?

Hvad er dens position i DOM-hierarkiet?

Arver den fra Node eller Element, eller måske HTMLElement?

Vi kan se, hvilken kalsse den tilhører ved at udskrive den, f. eks. sådan her:

alert(document); // [object HTMLDocument]

eller:

alert(document.constructor.name); // HTMLDocument

Så, document er en udgave af klassen HTMLDocument.

Hvad er dens position i hierarkiet?

Ja, vi kunne selvfølgelig gennemgå specifikationen, men det er måske hurtigere at finde ud af det manuelt.

Lad os gennemløbe prototypekæden via __proto__.

Vi ved følgende: Metoderne for en klasse findes i egenskaben prototype hos konstruktøren. For eksempel har HTMLDocument.prototype metoder for dokumenter.

Derudover er der en reference til constructor funktionen inde i prototype:

alert(HTMLDocument.prototype.constructor === HTMLDocument); // true

For at få et navn på klassen som en streng, kan vi bruge constructor.name. Lad os gøre det for hele document prototypekæden, indtil klassen Node:

alert(HTMLDocument.prototype.constructor.name); // HTMLDocument
alert(HTMLDocument.prototype.__proto__.constructor.name); // Document
alert(HTMLDocument.prototype.__proto__.__proto__.constructor.name); // Node

Det er hierarkiet.

Vi kunne også undersøge objektet ved hjælp af console.dir(document) og se disse navne ved at åbne __proto__. Konsollen henter dem internt fra constructor egenskaben.

Tutorial-oversigt

Kommentarer

læs dette før du kommenterer…
  • Hvis du har forslag til forbedringer - så opret venligst et GitHub-issue eller en pull request i stedet for at kommentere.
  • Hvis du ikke forstår noget i artiklen - så uddyb venligst.
  • For at indsætte få ord kode, brug <code>-taggen, for flere linjer - omslut dem i <pre>-tag, for mere end 10 linjer - brug en sandbox (plnkr, jsbin, codepen…)