Document Object Model (DOM)
- Käsitteitä
- Document
- Node
- Element
- Window
- CDATA
- HTMLCollection ja NodeList
- Huomioitavaa
- Selainten DOM-laajennokset
- Lisätietoa
DOM on standardi, jonka avulla voidaan manipuloida dynaamisesti XML- tai HTML-dokumenttien dokumenttipuuta.
Jos haluat lukea aiheesta kirjan niin lue DOM Enlightenment. Paras dokumentaatio löytyy Mozilla Development Networkin DOM-sivustolta.
DOM-standardista on useita eri versioita. Laajin rajapinta on selainympäristössä. Samaa, mutta suppeampaa rajapintaa, voi käyttää useimmilla ohjelmointikielillä.
Kukin elementti ja teksti muodostavat dokumenttipuuhun Node-tyypin olion. DOM:in tarjoamia attribuutteja ja metodeja voi tarkastella Firefoxissa DOM-työkalulla Tools|Web developer|Inspector.

Käsitteitä
- vanhempi-, äiti- tai isäelementti (engl. parent)
- elementti, jonka sisällä ko. elementti välittömästi on.
- lapsielementti (engl. child)
- välittömästi ko. elementin sisällä oleva elementti
- jälkeläinen (engl. descendant)
- ko. elementin sisällä oleva elementti
- esivanhempi, esiisä (engl. ancestor)
- elementti, jonka jälkeläinen ko. elementti on
- sisarelementti (engl. sibling)
- elementit ovat sisaret, jos niillä on yhteinen vanhempielementti
- edeltävä/seuraava sisarelementti (engl. preceding/following sibling)
- edeltävä elementti on dokumenttipuussa ennen ko. elementtiä, seuraava on sen jälkeen

Document
Document-tyyppinen document-objekti vastaa aina yhtä selaimeen ladattua www-sivua (window.document). Dokumentti sisältää varsinaisen DOM-puun. Dokumentti perii ominaisuudet ja metodit Node- ja EventTarget-luokilta.
Riippuen siitä onko kyseessä html-dokumentti vai xml-dokumentti voi dokumentin ja muiden objektien rajapinta olla erilainen. Html-dokumenteilla on laajennettu rajapinta. Tähän vaikuttaa suoraan dokumentin mediatyyppi (text/html vs application/xhtml+xml tai application/xml). Tyypillisimmillään erot ilmenevät dokumentin päätettä vaihdettaessa (.html vs .xhtml).
Dokumentin tärkeimpiä ominaisuuksia ovat:
- Document.body Dokumentin body-elementti
- Document.documentElement Dokumentin html-elementti
- Document.forms lista dokumentin kaikista lomakkeista (form-elementit)
- ParentNode.children Dokumentin kaikki lapsielementit
- Document.title Dokumentin otsikko (title-elementti)
- Document.URL Dokumentin osoite
Dokumentin tärkeimpiä metodeja ovat:
- Document.createElement() Luo dokumenttiin uusia elementtejä
- Document.createTextNode() Luo dokumenttiin uusia tekstinodeja
- Document.getElementsByClassName() Hakee elementtejä niiden class-attribuutin perusteella
- Document.getElementsByTagName() Hakee elementtejä niiden nimen perusteella
- Document.querySelector() Hakee ensimmäisen css-valitsinta vastaavan elementin
- Document.querySelectorAll() Hakee kaikki css-valitsinta vastaavat elementit
Node
Node on abstrakti pääluokka, johon perustuvat kaikki muut DOM-puussa esiintyvät objektit, joista tärkeimmät ovat Element ja Document.
Noden tarkka kuvaus löytyy MDN:n Node-sivulta. Tässä on lueteltu tärkeimmät ominaisuudet:
- Node.childNodes Kaikki lapsinodet
- Node.firstChild Ensimmäinen lapsinode
- Node.lastChild Viimeinen lapsinode
- Node.nextSibling Seuraava sisarnode
- Node.nodeName Noden nimi
- Node.nodeType Noden tyyppi
- Node.nodeValue Noden tekstisisältö, jos kyseessä on text-, comment-, attribuutti- tai CDATa-tyyppinen node. Kts. textContent-ominaisuus
- Node.parentNode äitinode
- Node.previousSibling edellinen sisarnode
- Node.textContent noden ja kaikkien sen lapsinodejen tekstisisältö
Esimerkki childNodes-, nodeType-, nodeValue- ja textContent-ominaisuuksista.
Noden tärkeimmät metodit ovat:
- Node.appendChild(childNode) Lisää noden viimeiseksi lapseksi uuden noden
- Node.cloneNode() Tekee nodesta kopion
- Node.contains() Testaa onko parametrina annettu node tämän noden lapsi tai jälkeläinen
- Node.hasChildNodes() onko nodella lapsia vai ei
- Node.insertBefore() Lisää noden lapseksi uuden noden annettua referenssinodea ennen
- Node.removeChild() Poistaa lapsinoden DOM-puusta
- Node.replaceChild() Korvaa lapsinoden toisella nodella
Element
Element perii kaikki Noden ominaisuudet. Näiden lisäksi Elementin tärkeimpiä ominaisuuksia ovat seuraavat:
- Element.className Elementin class-attribuutin arvo
- nextElementSibling Elementin seuraava sisarelementti
- previousElementSibling Elementin edellinen sisarelementti
- Element.clientHeight Elementin korkeus
- Element.clientWidth Elementin leveys
- Element.id Elementin id
- Element.tagName Elementin nimi
Elementillä on Nodelta perittyjen metodien lisäksi seuraavia tärkeitä metodeja:
- Eventtarget.addEventListener() Lisää elementille tapahtumankäsittelijän
- Element.getAttribute() Elementin halutun attribuutin arvo
- Element.getElementsByClassName() Hakee elementin jälkeläisistä elementtejä joilla on haluttu class
- Element.getElementsByTagName() Hakee elementin jälkeläisistä elementtejä joilla on haluttu nimi
- Element.hasAttribute() Testaa onko elementillä määritelty haluttu attribuutti
- Element.insertAdjacentElement() lisää annetun elementin ennen tai jälkeen elementtiä tai ennen elementin ensimmäistä lapsielementtiä tai elementin viimeisen lapsielementin jälkeen
- Element.querySelector() Etsii elementin lapsista ensimmäisen css-valitsimen perusteella
- Element.querySelectorAll() Etsii elementin lapsista kaikki annettua css-valitsinta vastaavat elementit
- ChildNode.remove() Poistaa elementin itsensä DOM-puusta
- Element.removeAttribute() Poistaa elementiltä attribuutin
- EventTarget.removeEventListener() Poistaa elementiltä tapahtumankäsittelijän
- Element.setAttribute() Asettaa halutulle attribuutille arvon
Window
Globaali window-muuttuja vastaa aina yhtä www-dokumentti-ikkunaa tai välilehteä. Window-muuttujan kautta pääsee käsiksi varsinaiseen dokumenttiin (window.document). Window-objektin ominaisuuksiin pääsee normaalisti käsin ilman window-objektin nimeä eli document on sama kuin window.document
Window-objektin tärkeimpiä ominaisuuksia ovat:
- Window.document Ikkunassa oleva dokumentti
- Window.localStorage sivustokohtainen tallennuspaikka
- Window.sessionStorage sessiokohtainen tallennuspaikka
Window-objektin tärkeimpiä metodeja ovat:
- Window.alert() alert-dialogi
- Window.confirm() OK/Cancel-dialogi
- Window.getComputedStyle() CSS-ominaisuuksien lasketut arvot
- Window.prompt() kyselydialogi
- Window.requestAnimationFrame() animointimetodi
CDATA
CDATA-lohkolla merkitään tekstit, jotka eivät ole XML/HTML-rakennetta.
<![CDATA[
Tähän väliin voi kirjoittaa mitä vaan eikä tämä riko sivun rakennetta. Voi
käyttää erikoismerkkejä &, < ja > ihan vapaasti.
]]>
HTMLCollection ja NodeList
NodeList-objekti sisältää kokoelman nodeja. NodeList-objekti voi olla staattinen tai elävä (live). Elävä Nodelist-objekti sisältää automaattisesti kaikki DOM-puuhun rakenteeseen tulleet muutokset. Staattinen NodeList-objekti ei päivity. Useimmat metodit palauttavat live-NodeListeja, mutta esim. document.querySelectorAll() palauttaa staattisen.
NodeListin voi läpikäydä kuten taulukon tavallisella for-silmukalla. Myös for..of-silmukka toimii moitteetta NodeListien kanssa. NodeList-objektia ei kuitenkaan pidä läpikäydä for..in-silmukalla.
HTMLCollection on samalla tavalla taulukkotyyppinen live-objekti kuten NodeList-objekti, mutta se sisältää vain elementtejä eikä kaikkia nodeja kuten NodeList.
Huomioitavaa
- DOM:in käsittely on "live" eli jos esimerkiksi olet läpikäymässä jonkun solmun lapsielementtejä ja poistat sieltä yhden niin läpikäytävä joukko muuttuu.
- Solmun siirtäminen tapahtuu hakemalla haluttu solmu ja liittämällä se toisen solmun lapsisolmuksi
appendChild-metodilla. Normaalisti solmuista ei tule kopioita vaan olioreferenssit liikkuvat vain vanhempielementiltä toiselle. - Teksti ei ole normaalin elementtisolmun ominaisuus vaan elementin
sisällä on usein
TextNode-tyyppinen solmu, jonka tekstisisällön saaNodeValue-metodilla. Koko elementin tekstisisällön saatextContent-ominaisuudesta. - Lomake-elementtien arvot saadaan value-attribuutilla
- Puun läpikäyminen vaatii usein rekursiota.
- Helpoin tapa saada tietty elementti on antaa sille
id-arvo ja pyytää sitädocument.getElementById-metodilla. - Monet metodit, kuten
getElementsByTagName, palauttavat listan solmuista, nämä pitää läpikäydä silmukassa ja pyytää yksittäin listaobjekti.item(i)-metodilla tai []-syntaksilla - Helpoin tapa tyhjentää DOM-puun solmu on asettaa sen tekstisisällöksi tyhjä merkkijono:
element.textContent = ""; - querySelector ja querySelectorAll voivat tietyissä tilanteissa toimia vähän eri tavalla kuin kuvittelemme. Lisätietoa: Element.querySelectorAll().
Selainten DOM-laajennokset
Kurssin materiaaleissa käytetään pääasiassa yleisiä DOM-rajapinnan metodeja. Tämä tarkoittaa, että samat metodit toimivat muuallakin kuin selainympäristössä. Esim. voisitte kirjoittaa python-ohjelman, joka käsittelee jotain XML-tiedostoja ja käytössänne olisi tismalleen samat metodit.
Selainympäristössä on kuitenkin sisäänrakennettuna useita lisäominaisuuksia, joista osaa voi myös käyttää. Esim. seuraavista metodeista voi olla paljonkin apua:
- HTMLElement
- HTMLInputElement
- HTMLDialogElement
- HTMLFormElement
- HTMLImageElement
- HTMLTableElement
- Location
- History
- ValidityState
- Navigator
Seuraavia EI PIDÄ KÄYTTÄÄ. Näiden käyttäminen voi aiheuttaa tietoturvaongelmia. Näillä saa myös rikottua DOM-puun rakenteen. Nämä eivät myöskään osaa huomioida erikoismerkkejä kuten <, > ja &.
- element.innerHTML
- element.insertAdjacentHTML
- element.outerHTML
Käyttäjien kommentit