JavaScript
Børre Stenseth
Omgivelsene >DOM

DOM (Document Object Model)

Hva

document er et objekt som er tilgjengelig i window, og så alle window-objekter kan vi nå objektet direktes som nettop document. Vi betrakter dokumentet som en struktur, en DOM (Document Object Model). Det betyr at alle komponentene, elementene, i dokumentet er ordnet i en hierarkisk trestruktur. Denne strukturen forutsetter at dokumentet er formet slik at det er mulig for parseren i nettleseren å sette opp en entydig XML-struktur. Vi vet at alle html-sider ikke er velformet (HTML5-standarden krever ikke velformethet i XML-betdning), men det er parserens jobb å tolke det den finner etter beste evne og presentere document som en veldefinert XML-struktur for oss som JavaScript-programmerere. Dagens nettlesere har utviklingsverktøy som gjør det mulig å inspisere denne strukturen og se hvordan den dynamisk endres når vi kjører javascrip mut strukturen. Du kan også se på et eksperiment i modulen Sidestruktur .

Eksemplene i denne modulen er ganske trivielle og har bare som hensikt å vise helt grunnleggende DOM-manipulering. Det er i prinsipp to angrepsvinkler til en slik DOM.

  • Vi kan bruke de basisrutinene som opprinnelig er utviklet for å arbeide med generelle XML-baserte DOM-trær. Det innebærer at vi har tilgjengelig egenskaper i alle elementer av typen: parentNode, childNodes firstChild, nextSibling og noen flere som gjør det mulig for oss å navigere i trestrukturen og vi finner funksjoner som lar oss manipulere strukture.
  • document-objektet tilbyr en rekke metoder som er spesielle for html-basert DOM.

Tell paragrafer

La oss se på et enkelt eksempel: Vi ønsker å telle antall paragrafer, p-elementer, på denne siden og vise resultatet i en alertboks. Vi prøver på to måter:

  1. Ved hjelp av allmenne DOM-metoder

    function inspect(elt,tagname){
    	var count=0;
    	if((elt.nodeType==elt.ELEMENT_NODE)&&
    	   (elt.nodeName.toLowerCase()==tagname))
    		count+=1;
    	var list=elt.childNodes;
    	for(var ix=0;ix < list.length;ix++)
    		count+=inspect(list[ix],tagname);
    	return count;
    }
    function countTags(tagname){
    	alert("Antallet "+tagname+" elementer: "+
    		  inspect(document.documentElement,tagname));
    }
  2. Ved hjelp av en html spesifikk DOM-metode

    Javascriptkoden blir svært enkelt og bruker bare en DOM-metode.

    function countTagsSimple(tagname){
    	alert("Antallet "+tagname+" elementer: "+
    		 document.getElementsByTagName(tagname).length);
    }

Det er klart at den siste måten er å foretrekke. getElementsByTagName() er en av mange spesifikke metoder vi finner i document-objektet for å finne elementer i DOM-strukturen:

	getElementsByTagName()
	getElementById()
	getElementByClassName()
	querySelectorAll()
	querySelector()

De to siste bruker CSS-selectorer som parameter. Disse to er nærmere beskrevet JS og CSS .

Vi kan også benytte en del egenskaper som ikke er direkte relatert til en DOM-tankegang. Vi kan be om følgende arrays av elementer direkte:

  • document.images
  • document.forms
  • document.links
  • document.scripts
  • document.plugins
  • document.styleSheets

Spesielt Form-programmering er verdt en nærmere inspeksjon. Du kan også se nærmere på dette her:

tester2 https://borres.hiof.no/wep/js/dom/tester2.html

Produksjon av innhold

La oss produsere en elementstruktur fra et javascript. Vi vil legge til litt formatert text inn i et element. Igjen gjør vi det på to måter.

  1. Dette er originalteksten, i en div med id=makemore.
    function makeMore(hostID)
    {
       hostelement=document.getElementById(hostID);
       newelt=document.createElement('div');
       newtext=document.createTextNode('... og her er mer');
       newelt.style.color='red';
       newelt.appendChild(newtext);
       hostelement.appendChild(newelt);
    }

    Koden er ganske omstendelig og demonstrerer bruk av grunnleggende DOM-metoder.

  2. Dette er originalteksten, i en div med id=makemore2.
    function makeMore2(hostID)
    {
       hostelement=document.getElementById(hostID);
       hostelement.innerHTML=hostelement.innerHTML+
        '<div style="color:red">... og her er mer</div>';
    }

    Vi ser at innerHTML aksepterer html-kode. Denne koden parses i det øyeblikk den plasseres i dokumentet. Merk at dersom vi hadde plassert ut en script-tag med JavaScript måttet vi eksplisitt ha bedt om å få den parset.

Bytte innhold i elementer

Dette er en ganske generell problemstilling som kan tjene som illustrasjon av noe av den mest sentrale funksjonaliteten. Vi ønsker altså å bytte innholdet i to elementer som respons på en eller annen brukeraksjon. Du kan test ut eksempelet her.

Hallo
Hei

De involverte linjene i HTML-siden er slik:

<div id="linje1"><span style="color:red">Hallo</span></div>
<div id="linje2"><span style="color:green;font-size:20px;">Hei</span></div>
<div>
 <button class="demobutton" 
         onclick="switchElements('linje1','linje2');">
         Bytt linjene
</button>
</div>

Javascriptet ser slik ut:

function switchElements(elt1ID,elt2ID)
{
    element1=document.getElementById(elt1ID);
    element2=document.getElementById(elt2ID);
    temptext=element1.innerHTML;
    element1.innerHTML=element2.innerHTML;
    element2.innerHTML=temptext;
}

Vi kan bruke den samme teknikken for bilder. Prøv å føre musa inn og ut av dette bildet og se hva som skjer.

image1

Den aktuelle koden er slik:

<div id="div1" style="cursor:pointer">
   <img src="Smileys17.gif" alt="image1"
   onmouseover="switchElements('div1','div2');"/>
</div>
<div id="div2" style="display:none">
   <img src="Smileys12.gif" alt="image2"
   onmouseout="switchElements('div1','div2');"/>
</div>

Alternativt kan vi gjøre slik hvis vi f.eks. ønsker å markere en popup. Prøv å klikk på bildet.

image1
<div id="div11" style="cursor:pointer">
   <img src="Smileys17.gif" alt="image1"
   onmouseover="switchElements('div11','div12');"/>
</div>
<div id="div12" style="display:none">
   <img src="Smileys12.gif" alt="image2"
   onmouseout="switchElements('div11','div12');"
   onclick="simplepopup('demo2.html','Pop','*')"/>
</div>

Skjulte elementer

Vi ser at en teknikk som er bruk ovenfor er å legge ut deler av vevsiden med style="display:none", for så å flytte innholdet i et slikt skjult element til et element som ikke er skjult. Og/eller omvendt. Dette åpner i prinsipp for at vi kan ommøblere en vevside som som vi vil med en enkel "switchElements()" og/eller "copyElement()" funksjon. Vi skal senere se at vi kan oppnå denne effekten med å manipulere class-attributten eller selve CSS beskrivelsen

Eksempel

Galleri https://borres.hiof.no/wep/js/dom/demo1.html

Oversikt

document-objektet er nøkkelen til det meste av det vi gjør når vi skal manipulere en vevside. Det er document-objektet som gir oss tilgang til komponentene på en side, elementene. Alle disse komponentene gjøres tilgjengelige for oss som noder av forskjellig type og med forskjellige egenskaper.

Hvis du vil ha en komplett liste av alle egenskaper og metoder i dette document-objektet slik din nettleser finner dem kan du kjøre følgende script:

function visDocInfo()
{
  var elt=document.getElementById("visdocinfo");
  if(elt.innerHTML.length > 10){
    elt.innerHTML='';
    return;
  }
  var S='<table border="1px" cellspacing="0px" width="500px">';
  for(p in document)
  {
    try{S+='<tr><td>'
    +p
    +'</td><td>'
    +document[p]
    +'</td></tr>';}
    catch(E){S+='<tr><td>'
    +p
    +'</td><td style="color:red">'
    +E.message
    +'</td></tr>';}
  }
  S+='</table>';
  elt.innerHTML=S;
}
Omgivelsene >DOM