Javascript: Document Object Model DOM

  1. Inleiding
  2. DOM - versies
  3. DOM 0
  4. Tussenliggende DOM's
  5. W3C DOM: elementen manipuleren, elementen toevoegen en verwijderen
  6. Objectdetectie
  7. Oefeningen

Inleiding

Het Document Object Model (DOM) beschrijft hoe alle elementen op een webpagina (figuren, links, textvakken,...) gerelateerd zijn ten opzichte van het document als hoofdelement.

Via het DOM kan je de elementen op een webpagina manipuleren: eigenschappen opvragen en zelfs veranderen.

Het is in dit hoofdstuk dat we afscheid nemen van het eerder theoretische eerste gedeelte van de cursus en ons meer zullen verdiepen in dynamische toepassingen.

DOM - versies

Het begrip DOM voor webpagina's werd meegeïntroduceerd met Javascript. We beschikken met Javascript over een taal waarmee we webpagina's dynamisch kunnen maken. In de voorbije hoofdstukken hebben we de basis van Javascript doorgenomen, het is nu tijd deze basiskennis in de praktijk te brengen met dynamische toepassingen.

Voor webontwikkelaars is het belangrijk de eigenschappen van elementen op een webpagina te kunnen beïnvloeden. Wil je een figuur laten veranderen wanneer de gebruiker er met de muis over beweegt, dan moet je de eigenschap src van het element IMG kunnen aanpassen.

Het DOM heeft ondertussen reeds een behoorlijk ontwikkeling doorgemaakt:

  1. DOM 0: originele DOM ontworpen door Netscape. Wordt nog steeds door zowat alle browsers ondersteund.
  2. Tussenliggende DOM's: met de introductie van de versie 4 browsers was DHTML het toverwoord op het internet. Plots moesten op webpagina's tal van dynamische effecten mogelijk zijn. Netscape en Microsoft gingen hier elk hun eigen weg. Netscape maakt gebruik van document.layers en Microsoft van document.all
  3. W3C DOM: standaard voorgesteld door het W3C, reeds level 3 in ontwerp.

Meer over de DOM-levels bij Mozilla en W3C en W3Schools.

DOM 0

Daar nog tal van websites gebruik maken van de originele specificaties van DOM, is het onontbeerlijk dit model te bestuderen.

Niveau 0 van DOM is relatief eenvoudig: document is het hoofdobject en daaronder heb je toegang tot images, links, forms en anchors.

Images

Om de eigenschap src van een IMG aan te passen kan je de volgende opdracht gebruiken:

document.images[0].src = "figuurnaam"
Images vormt hier in feite een Array van alle figuren op de webpagina. Bovenstaande opdracht zal dus de eerste figuur op de pagina veranderen.

Op deze manier kunnen we een andere afbeelding laten verschijnen wanneer de muisaanwijzer boven de figuur komt. We moeten er wel voor zorgen dat de figuur weer in het origineel verandert wanneer de muisaanwijzer de figuur verlaat.

In het voorbeeld wordt het veranderen van de src van de figuur gedaan door vanuit de eventhandlers onmouseover en onmouseout telkens een functie aan te roepen.

<HTML>
<HEAD>
 <TITLE>Cursus HTML - IVO Brugge</TITLE>
 <LINK href="../../vb.css" rel="stylesheet" type="text/css">
 <script type="text/javascript">
<!--
	function over(){
		document.images[0].src = "../../images/schapen.jpg"
	}
	
	function uit(){
		document.images[0].src = "../../images/koeien.jpg"
	}

// -->
</script>
</HEAD>
<BODY>

<h1>Toepassing DOM 3</h1>
<img src="../../images/koeien.jpg" width="141" height="94" alt="" border="0" 
    onmouseover="over()" onmouseout="uit()">
</BODY>
</HTML>

Aangezien je vaak niet zeker bent dat deze figuur steeds de eerste figuur zal zijn op de pagina kan je deze ook een uniek id of name toekennen.

<HTML>
<HEAD>
 <TITLE>Cursus HTML - IVO Brugge</TITLE>
 <LINK href="../../vb.css" rel="stylesheet" type="text/css">
 <script type="text/javascript">
<!--
	function over(){
		document.images["dier"].src = "../../images/schapen.jpg"
	}
	
	function uit(){
		document.images["dier"].src = "../../images/koeien.jpg"
	}

// -->
</script>
</HEAD>
<BODY>

<h1>Toepassing DOM 0</h1>
<img id="dier" src="../../images/koeien.jpg" width="141" height="94" alt="" border="0" onmouseover="over()" onmouseout="uit()">
</BODY>
</HTML>

Forms

Het gebruik van formulieren is heel belangrijk voor ontwikkelingen met Javascript.

Formulieren zijn op webpagina's de elementen waarmee interactie en input van de gebruiker kan ontvangen.

Hieronder enkele manieren om formulieren en elementen uit formulieren te adresseren:

    // eerste formulier op de pagina
  document.forms[0]
  
    // formulier met de naam f
  document.forms["f"]     
  
    // derde element van het formulier met naam f         
  document.forms["f"].elements[2] 
  
    // element product van het formulier f
  document.forms["f"].elements["product"]
  
    // waarde van het element product uit formulier f
  document.forms["f"].elements["product"].value
  
    // verkorte notatie van dit laatste
  f.product.value

Toepassing:

<HTML>
<HEAD>
 <TITLE>Cursus HTML - IVO Brugge</TITLE>
 <LINK href="../../vb.css" rel="stylesheet" type="text/css">
 <script type="text/javascript">
<!--
	function bereken(){
		f.product.value = f.g1.value * f.g2.value
	}
	

// -->
</script>
</HEAD>
<BODY>

<h1>Toepassing DOM 0</h1>
<form name="f">
<table>
<tr>
       <td>Getal 1: </td>
       <td><input name="g1" type="text" value="10"></td>
</tr>
<tr>
       <td>Getal 2: </td>
       <td><input name="g2" type="text" value="50"></td>
</tr>
<tr>
       <td>Som: </td>
       <td>
	   		<input name="product" type="text" value="">
			<input type="button" value="Maak product" onclick="bereken()">
	   </td>
</tr>
</table>
</form>
</BODY>
</HTML>

Tussenliggende DOM's

Na DOM 0 ontwikkelden Netscape en Microsoft op eigen houtje een eigen DOM.

Netscape koos voor document.layers, waarbij ze hun eigen filosofie volgden en ook een nieuwe tag LAYER gingen gebruiken. Deze DOM zullen we niet verder bespreken daar zelfs Netscape nu is afgestapt van deze DOM.

Microsoft ging werken met document.all: één object-collectie van waaruit je alle elementen op de pagina kan bereiken.

Voorbeeld document.all:

In de functie verdubbel wordt eerst gecontroleerd of document.all wordt ondersteund:

if(document.all)
<HTML>
<HEAD>
 <TITLE>Cursus HTML - IVO Brugge</TITLE>
 <LINK href="vb.css" rel="stylesheet" type="text/css">
 <script type="text/javascript">
 <!--
	function verdubbel(){
		if(document.all){
			document.all["g1"].value = 2 * document.all["g1"].value;
		}
	}
 // -->
 </script>
</HEAD>
<BODY>

<h1>Tussendom: document.all</h1>
<form name="f">
<input id="g1" type="text" value="10">
<input type="button" value="Verdubbel" onclick="verdubbel()">
</form>
</BODY>
</HTML>

W3C DOM

Inleiding

De DOM voorgesteld door het W3C wordt in level 1 door Nescape en IE 5+ ondersteund, level 2 door de versie 6 - generatie.

In de W3C DOM is elk object, wat het ook is, een node:

<p>Dit is een alinea</p>
Hier maken we twee nodes: een elementnode voor het element P en een tekstnode voor de inhoud. De tekstnode zit in de elementnode en wordt beschouwd als een childnode.
<p>Dit is <b>een alinea</b></p>
Hier hebben we een elementnode P, deze node heeft als childnodes een tekstnode voor de inhoud 'Dit is' en een elementnode B. Deze elementnode heeft een childnode voor de inhoud 'een alinea'.
<p align="right">Dit is <b>een alinea</b></p>

De laatste nodes zijn attribuutnodes. De elementnode voor P heeft een attribuutnode align met een child-tekstnode 'right'.

Attribuutnodes worden niet als childnodes van een elementnode beschouwd.

Elementen manipuleren

Om een element te manipuleren moet je vanuit Javascript eenduidig kunnen opgeven met welk element je wenst te werken.

Methode Beschrijving
getElementByID Referentie naar het element met aangegeven attribuut id
getElementsByName Referentie naar element(en) met aangegeven name
getElementsByTagName Referentie naar aangegeven elementen

Deze mogelijkheid van het DOM stelt je in staat de inhoud en attribuutwaarden van elk element te manipuleren.

De eenvoudigste manier om dit te bereiken is gebruik maken van de methode getElementById van het object document:

document.getElementById("kop")
deze opdracht vormt een referentie naar het element met id kop.

Inhoud veranderen:

We hebben bijvoorbeeld een element met id tekst1

Wil je de inhoud van dit element veranderen, dan kan je dit volgens de W3CDOM op volgende manier:

document.getElementById("tekst1").firstChild.nodeValue='De tekst is veranderd !';
Probeer het:

Originele tekst

Je kan ook met de innerHTML-eigenschap van een element werken:

document.getElementById("kop2").innerHTML ='Ook aangepast !';
Probeer het:

Originele tekst

Attribuutwaarde veranderen:

Hier hebben we een element met id uitlijn.

Op volgende manier kan je de uitlijning van deze alinea op 'right' instellen:

node = document.getElementById('uitlijn');
node.setAttribute('align','right');
Links uitlijnen | Rechts uitlijnen

Tekst in een alinea

Nodes maken en verwijderen

De mogelijkheden met DOM zijn van die aard dat je zelfs nieuwe elementen op een pagina kan plaatsen en bestaande elementen kan verwijderen.

We voegen in onderstaande toepassing een HR-element toe aan de pagina.

Maak lijn | Verwijder lijn

Dit is een alinea

Het HR-element wordt toegevoegd als child-element van het element met id alinea.

var x = document.createElement('HR');
document.getElementById('alinea').appendChild(x);

We maken het HR-element met de methode createElement van het object document en plaatsen het in een variabele x.
We voegen het element toe als child van het element alinea met de methode appendChild.

Het verwijderen van dit element gebeurt als volgt:

var node = document.getElementById('alinea');
if(node.childNodes[1]) node.removeChild(node.childNodes[1]);

We plaatsen een referentie naar het element alinea in de variabele node.
We controleren of deze node reeds een tweede childNode heeft (de eerste childNode met index 0 is de inhoud van de alinea).
Als deze node bestaat, werd de lijn reeds op het scherm gezet en kunnen we ze verwijderen met de methode removeChild van het element. Deze methode ontvangt als argument de te verwijderen node.

Objectdetectie

Browserdetectie

Misschien werk je wel met een browser waarbij bepaalde van bovenstaande toepassingen niet functioneren. Als webontwikkelaar hebben we natuurlijk niet te kiezen met welke browser de gebruiker onze pagina's bezoekt.
Daarom moeten we ervoor zorgen dat deze gebruiker niet om de oren wordt geslagen met javascript-errors.

Met dit doel voor ogen is het dus interessant te weten met welke browser de gebruiker werkt, daar de implementatie van het DOM verschilt naargelang de gebruikte browser.

Met Javascript kan je eenvoudig nagaan welke instellingen de gebruiker heeft:

document.write(navigator.userAgent);

U werkt met:

Met de geziene String-functies kan je nu heel eenvoudig testen welke browser er gebruikt wordt.

Objectdetectie

In feite is voor het ontwikkelen van cross-browser toepassingen niet zozeer van belang met welke browser de gebruiker surft, maar wel de wetenschap of de door jou gebruikte technieken door die browser worden ondersteund.

Het is heel vervelend voor toepassingen steeds te moeten uitzoeken welke browser de techniek ondersteund, en dan nog telkens uw code aan te passen wanneer een browser een nieuwe versie uitbrengt.

Vandaar dat het ten zeerste aan te raden is objectdetectie te gebruiken.

Controle document.images (DOM 0)

if(document.images){
	... code met document.images ...
}

Controle op document.getElementById (DOM 1)

if(document.getElementById){
	... code met document.getElementById ...
}

Cross browser toepassingen

Wanneer je een cross-browser toepassing maakt en je wenst een verwijzing naar een object te maken, dan ben je niet absoluut zeker dat getElementById ondersteund wordt door de browser.

Onderstaande functie detecteert welke de mogelijkheden van de browser zijn en bouwt een referentie op:

function getObj(name)
{
  if (document.getElementById)
  {
  	this.obj = document.getElementById(name);
  }
  else if (document.all)
  {
	this.obj = document.all[name];
  }
  else if (document.layers)
  {
   	this.obj = document.layers[name];
  }
}

Deze functie is afgeleid van de DHTML API op de site van quirksmode.

Gebruik van deze functie:

Deze functie vormt eigenlijk een constructor-functie. We kunnen deze functie gebruiken als sjabloon om objecten aan te maken.

var x = new getObj('idvanelement');

Deze functie zorgt ervoor dat de variabele die we gebruiken een object zal bevatten met de eigenschap obj, met deze eigenschap hebben we toegang tot de html-eigenschappen van het element dat we meegeven aan de getObj-functie.

<HTML>
<HEAD>
 <TITLE>Cursus HTML - IVO Brugge</TITLE>
 <LINK href="vb.css" rel="stylesheet" type="text/css">
 <script type="text/javascript">
<!--
    function verandertekst(tekst)
    {
		var x = new getObj('kop');
		x.obj.innerHTML = tekst;
    }
	
	function getObj(name){
  		if (document.getElementById){
  			this.obj = document.getElementById(name);
  		}
  		else if (document.all){
			this.obj = document.all[name];
  		}
  		else if (document.layers){
   			this.obj = document.layers[name];
  		}
	}
-->
</script>
</HEAD>
<BODY>
<h1 id="kop">Hoofding</h1>
<a href="javascript:verandertekst('test')">Test</a> | 
<a href="javascript:verandertekst('Nog eens')">Nog eens</a>
</BODY>
</HTML>

Extra uitleg: werken met objecten en eigenschappen

<HTML>
<HEAD>
 <TITLE>Cursus HTML - IVO Brugge</TITLE>
 <LINK href="vb.css" rel="stylesheet" type="text/css">
 <script type="text/javascript">
<!--
	
	function persoon(n,v,l){
  		this.naam = n;
		this.voornaam = v;
		this.leeftijd = l;
	}
	
	var p1 = new persoon("Peters","Jan",45);
	var p2 = new persoon("Janssens","Sofie",23);
	
-->
</script>
</HEAD>
<BODY>
<script type="text/javascript">
<!--
 	document.write("<br>" +p1.naam);
	document.write("<br>" +p2.voornaam);
-->
</script>
</BODY>
</HTML>

De functie persoon vormt hier een constructorfunctie voor persoon-objecten.

Een persoon maken we door een variabele te declareren als new persoon, we geven drie argumenten mee: de naam, voornaam en leeftijd van de persoon.
Deze drie argumenten worden in de constructor-functie persoon ontvangen onder de variabelenamen n, v en l. In deze constructorfunctie verwijst this naar de objectvariabele die je wenst te declareren: eerst p1, daarna p2.

Het resultaat van deze code is dat we 2 persoonsobjecten p1 en p2 hebben met elk drie eigenschappen: naam, voornaam en leeftijd.

Deze eigenschappen kunnen we opvragen door de naam van het object te noteren gevolgd door een punt en de naam van de eigenschap.

Meer tutorials:
leer ook: html | xhtml | css | asp | asp.net | c# | ado.net | linq | ajax | java | javascript
Valid HTML 4.01! Valid CSS! © - Cursusweb