2010-08-16 14:02 #0 av: johan-ahlback

Den här gången kommer det att handla om DOM och hur du kan påverka en sida utan att blanda javascript och html.

DOM står för document object model. Varje element som finns på en sida blir ett objekt. det är allt från html taggar till text. Det betyder att det även finns en massa metoder som hör till de objekten. Man säger att varje element blir en nod.

DOM är great!
om du läst första delen vet du att man ska dela upp de olika lagren på en hemsida. html, css och javascript ska hållas isär. Men hur ska man då komma åt de elementen om man inte får skriva onClick i en a tagg? jo man kan ge den länken ett id eller ett klassnamn. Med hjälp av DOM kan javascriptet komma åt den noden utan att behöva blanda.

Släktskap
noder har olika släktskap med varandra. kolla på det här exemplet:

<div>
<p>
<a href="#"><img src="#" />bildtext</a>
</p>

<p>
lorem ipsum
</p>
<div>

För att förklara släktskapet:
DIV är parent (förälder) till de båda P noderna, de blir alltså syskon (siblings) eftersom båda är barn (child) till DIV. och så går det neråt. Den här bilden är byggd som ett litet släktträd och där kan du se mycket lättare:

nod träd

Det kan vara värt att hålla koll på de olika noderna då man ganska ofta brukar vandra emellan dem. Ett tipps är att installera DOM inspector i firefox. Där kan du se en sidas nod träd.

Window och document
Det här är två viktiga objekt som används ofta tillsammans med metoder och egenskaper. För att starta en funktion när sidan laddas klart skriver man till exempel window.onload. Window onload är viktig för dig att kunna för att om skriptet körs på en gång så hinner inte noderna komma fram och då kan inte javascript komma åt dem. för att hämta en nod med ett id skriver man document.getElementById(id).

Metoder och egenskaper
Som jag sa innan finns det metoder till varje objekt, det gäller även objekt i DOM. Med vissa hämtar man information från noder, andra ändrar man med och vissa hämtar noder.
en lista med egenskaper:

* x.innerHTML - text värdet av x
* x.nodeName - namnet på x
* x.nodeValue - värdet (value) i x
* x.parentNode - föräldern till x
* x.childNodes - barnen för x
* x.attributes - attributen för x


en lista på metoder:

* x.getElementById(id) - hämtar noden med ett id
* x.getElementsByTagName(name) - hämtar alla noderna med ett namn
* x.appendChild(node) - lägger till ett barn för x
* x.removeChild(node) - tar bort ett barn från x


vissa kan även användas för att ändra värdet som innerHTML. Men jag råder till att använda setAttribute(). om jag vill ge x ett id så skriver man

setAttribute("id", "menu");

Med innerHTML kan man bestämma vad som finns i en nod.

det här ger en p tagg med text i noden x:

x.innerHTML("<p>hello world!</p>");

Men jag råder till att inte använda den till svårare saker då det kan bli svårt att underhålla. Jag ska visa hur man ska göra senare i den här delen. Men Först:

Tillbaka till arrayer
Nu kommer anledningen till varför du ska kunna arrayer om du vill skapa sidor som har javascript. Vi säger att du ska färga varannan länk som ligger i en div med id box. visst kan du ge varannan länk en klass, men nu vill du göra det med javascript för du vill att användaren ska bestämma om det ska vara så eller inte. men hur ska man göra då? Jo vi ska använda oss av DOM, en for loop och en if sats med modulo. så här gör vi då:

function links(){
var div = document.getElementById("box");
var links = div.getElementsByTagName("a");
var length = links.length;

for (var i = 0; i <= length; i++ ){
if (i%2 === 0){
links[i].setAttribute("class", "even");
}
}
}

window.onload = links;

först skapar vi en funktion så att scriptet inte körs på en gång och startar den med window.onload. I funktionen så hämtar vi en nod med id box. sen hämtar vi alla child noder som är a taggar. det är här arrayer kommer in i bilden. Notera skillnaden mellan att hämta ett id och att hämta flera noder. När det finns en risk att det det finns flera noder (taggar, classnamn osv) så placeras de i en array. sen är det en vanlig for loop och en if-sats som använder modulo(%). om du läst de tidigare delarna vet du att modulos resultat ger ett heltal som är kvar från en division. alltså om variabeln i dividerat med 2 ger ett rest så blir resultatet 1 och är ett udda tal om det inte blir en rest så är resultatet 0 , jämt tal. så om det är ett jämt tal, ta värdet från index i och ge den ett klassnamn.

Sen styr man hur den klassen ska se ut i css. För komm ihåg att skilja på lagren.

vandra mellan noder.
att man vandrar mellan noder är inget ovanligt. Om man klickar på en länk så ska den förälder byta klass. man kan ju lösa det med ett unikt id för varje men det är inte så bra. Så om vi ska komma åt en länks förälder när ett click event avfyras så måste vi säga att den här nodens förälder till skriptet. och det är preis vad vi ska göra på engelska. Vi ska säga att this.parentNode ska få ett klassnamn:

function changeClass(){
var links = document.getElementsByTagName("a");
alert(links);
for (var i = 0; i <= links.length; i++){
links[i].onclick = function(){
var parent = this.parentNode;
parent.setAttribute("class", "red");
}
}
}

window.onload = changeClass;

anledningen till for loopen är att vi måste säga att varje objekt i arrayen ska ha ett onclick event. annars är det nog inga konstigheter.

Hur lägger man till noder?
Det här är viktigt att veta. Man kan använda innerHTML men det ger ett skript som är svårt att underhålla. Istället ska vi skapa element och lägga till dem i noder, efter noder eller före noder. det kan se mer komplicerat ut än att använda innerHTML men när du skapar avancerade nodträd i javascript förstår du varför man inte ska använda den. Jag ska skapa en div som innehåller en a tagg för att demonstrera. jag kommer även att ge dem class namn och sen placera dem i en nod som har id box:

function createNodes(){
var div = document.createElement("div");
div.setAttribute("class", "linkbox");

var link = document.createElement("a");
link.setAttribute("class", "link");
link.setAttribute("href", "#");

var myText = document.createTextNode("Länk");

link.appendChild(myText);
div.appendChild(link);

document.getElementById("box").appendChild(div);
}


window.onload = createNodes;

jag tror inte att den här koden behöver så mycket förklaring. jag skapar element och sen behandlar jag dem som vanliga objekt. sen börjar jag lägga ihop allt.

Nu kan Du skilja på lagren
lägg alla dina javascript koder i ett separat document med ändelsen .js. sen länkar du in det i head genom att skriva:

<script type="text/jaascript" src="fil.js"></script>

i det documentet startar du första funktionen med window.onload. Sen är det bara att hämta noder med de metoder jag visat.


Behöver du kunna allt det här?
Mitt svar är nej. du behöver bara veta vad det handlar om. i nästa del kommer jag att gå igenom jquery's grunder. Och som det står på jquerys hemsida: "write less, do more". Jquery är ett javascript bibliotek med en massa funktioner, objekt, metoder och egenskaper som gör det enkelt att använda javascript. Om du kan html, css och lite dom så räcker det för att använda jquery. Jag kan lova att jquery gör javascript lätt. Även om du bara kan skapa enkla saker med javascript så kan du med jquerys hjälp skapa animationer. men mer om det nästa gång!