Teoria de DOM

De Wikijoan
Dreceres ràpides: navegació, cerca

Contingut

Introducció

El HTML DOM (Document Object Model, Model d'Objectes del Document) defineix un estàndar per accedir i manipular els elements d'un document HTML.

El DOM presenta un document HTML en una estructura d'arbre.

Referències

HTML DOM Objects Reference

Important:

DOM: L'arbre de nodes. Mètodes i propietats

DOM: Accedint als elements. Modificar, crear i eliminar elements

DOM i events

DOM: Navegant pel DOM

Aclaracions

No cal utilitzar sempre el getElementById

<!DOCTYPE html>
<html>
<head>
<script>
function myFunction() {
    var x = document.getElementById("fname");
    x.value = x.value.toUpperCase();
}
</script>
</head>
<body>

Enter your name: <input type="text" id="fname" onchange="myFunction()">
<p>When you leave the input field, a function is triggered which transforms the input text to upper case.</p>

</body>
</html>

Millor aquesta versió:

<!DOCTYPE html>
<html>
<head>
<script>
function myFunction(elem) {
    //var x = document.getElementById("fname");
    elem.value = elem.value.toUpperCase();
}
</script>
</head>
<body>

Enter your name: <input type="text" onchange="myFunction(this)">
<p>When you leave the input field, a function is triggered which transforms the input text to upper case.</p>

</body>
</html>

Adding event handler

<html>
<head>
<title>Adding event handler</title>
</head>
<body>
	<p id="paragraf">Adding event handler</p>
	<script>
	document.getElementById("paragraf").onclick=function(){alert('Adding event handler')}
	</script>
</body>
</html>

El id ha de ser únic

El programador s'ha de preocupar que un id no estigui repetit. En cas de què estigui repetit, s'agafa el primer:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
</head>
<body>

<a href="www.google.es" id="intro">Vés al Google</a>
<p id="intro">Hello World!</p>

<p>This example demonstrates the <b>getElementById</b> method!</p>

<script>
x=document.getElementById("intro");
document.write("<p>The text from the intro paragraph: " + x.innerHTML + "</p>");

document.write ('<br />');

document.write("<p>The text from the intro paragraph: " + document.getElementById("intro").innerHTML + "</p>");

</script>

</body>
</html>

Exemple getElementsByName

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
</head>
<body>

<a href="www.google.es" name="intro">Vés al Google</a>
<p name="intro">Hello World!</p>

<p>This example demonstrates the <b>getElementsByName</b> method!</p>

<script>
x=document.getElementsByName("intro");
document.write (x.length);
document.write ('<br />');
document.write (x[0].innerHTML);
document.write ('<br />');
document.write (x[1].innerHTML);
document.write ('<br />');

for (i=0; i<x.length; i++) {
document.write (x[i].innerHTML + '<br />');
}

</script>

</body>
</html>

vehicles.html:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
</head>
<body>

<form action="">
<input type="checkbox" name="vehicle" value="Bike">Bike<br />
<input type="checkbox" name="vehicle" value="Car" >Car</input><br />
 <input type="checkbox" name="vehicle" value="Plane" >Plane</input><br />
 <input type="checkbox" name="vehicle" value="Boat" >Boat</input><br />
 <input type="checkbox" name="vehicle" value="Skate" >Skate</input><br />
 <input type="checkbox" name="vehicle" value="BTT" >BTT</input><br />
 <input type="checkbox" name="vehicle" value="Surf" >Surf</input><br />
 <input type="checkbox" name="vehicle" value="Overcraft" >Overcraft</input><br />
</form>
<script>
vehicles=document.getElementsByName("vehicle");

for (i=0; i<vehicles.length; i++) {
document.write (vehicles[i].value  + '<br />');
}

</script>
</body>
</html>

onchange, onkeyup... Vols jugar al Pong?

En l'anterior exemple vist a classe convertim el text a majúscules en el moment de sortir del focus. Com es faria si volem convertir a majúscules a mida que anem pitjant les tecles?

onkeypress i onkeeydown no fan el resultat desitjat. En canvi, onkeyup sí que és la solució.

Per cert, vols jugar al Pong? Aquest joc utilitza els mètodes del teclat per fer moure la raqueta per la pantalla. Tens disponible tot el codi per estudiar-lo.

Compte amb el document.write

<html>
<head>
<title>Adding event handler</title>
</head>
<body>
	<p id="paragraf">No es pot utilitzar document.write després de què es carregui tota la pàgina</p>
	<script>
	document.write ("<br />Això s'escriu");
	document.getElementById("paragraf").onclick=function(){document.write ('esborra tot')}
	</script>
</body>
</html>

Problemes de sintaxi

Parlant d'events, fixem-nos que en aquest exercici s'utilitza style="background-color" (sintaxi CSS) i obj.style.backgroundColor (sintaxi Javascript). Aquesta disparitat de sintaxi és un problema afegit per a l'aprenentatge dels mètodes i propietats a utilitzar. No hi ha altra solució que acostumar-se a aquest fet...

<!DOCTYPE html>
<html>
<body>

<div onmouseover="mOver(this)" onmouseout="mOut(this)" style="background-color:#D94A38;width:120px;height:20px;padding:40px;">Mouse Over Me</div>

<script>
function mOver(obj)
{
obj.innerHTML="Thank You";
obj.style.backgroundColor="#0000ff";
}

function mOut(obj)
{
obj.innerHTML="Mouse Over Me";
obj.style.backgroundColor="#ff0000";
}
</script>

</body>
</html> 

3 maneres de fer events

Estudia bé aquest exemple:

<!DOCTYPE html>
<html>
<head>
<script>
function myFunction() {
    var x = document.getElementById("fname");
    x.value = x.value.toUpperCase();
}
</script>
</head>
<body>
<!--
1a manera de fer events:
Enter your name: <input type="text" id="fname" onchange="myFunction()">
-->

Enter your name: <input type="text" id="fname">
<p>When you leave the input field, a function is triggered which transforms the input text to upper case.</p>
<script>
//2a manera de fer events:
//document.getElementById("fname").onkeypress = function(){myFunction()};

document.getElementById("fname").onkeypress = myFunction;

//3a manera de fer events:
//document.getElementById("fname").addEventListener("keypress", myFunction);


</script>
</body>
</html>

Exemple childNodes

childNodes.html:

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8">
<body>

<div id="id01" style="background-color:yellow;">Node Text1 del DIV
   <p id="id02">aaa</p>Node Text2 del DIV
   <p id="id03">bbb</p>Node Text3 del DIV
   <p id="id04">ccc</p>Node Text4 del DIV
   <p id="id05">ddd</p>Node Text5 del DIV
</div>
<br />
<script>
var x = document.getElementById("id01");
var str = "Núm nodes: " + x.childNodes.length + "<br />";

for (var i=0; i<x.childNodes.length;i++) {
	//nodeName Property
	//nodeValue Property
	//nodeType Property
	str += "nodeName: " + x.childNodes[i].nodeName + " - ";
	str += "nodeValue: " + x.childNodes[i].nodeValue + " - ";
	str += "nodeType: " + x.childNodes[i].nodeType + "<br />";
}
//x.childNodes[0].nodeValue = x.id;
document.write(str);
</script>
<br /><br />
<script>
//https://www.w3schools.com/jsref/prop_node_nodevalue.asp
// If the node is an element node, the nodeValue property will return null.
// Note: If you want to return the text of an element, remember that text is always inside a Text node, and you will have to return the Text node's node value (element.childNodes[0].nodeValue).
document.write("Si volem accedir al contingut dels paràgrafs:<br />");
y = x.childNodes[1];
document.write(y.innerHTML + "<br />"); //aaa
document.write(y.nodeValue + "<br />"); //null
document.write(y.childNodes[0].nodeValue + "<br />"); //aaa
document.write(x.childNodes[1].childNodes[0].nodeValue + "<br />"); //aaa


</script>
</body>
</html>

NOTA: Fixem_nos bé que un caràcter de retorn de carro és un caràcter ASCII, i per tant és un node de text. És per això que aquesta peça de codi té 4 nodes de text amagats:

<div id="id01" style="background-color:yellow;">
<p id="id02">aaa</p>
<p id="id03">bbb</p>
<p id="id04">ccc</p>
</div>

Exemple childNodes II (vist a classe, 20.11.2018)

<!DOCTYPE html>
<html>
<body>

<div id="div1">
<p id="p1">This is a paragraph.</p><br />
<p id="p2">This is another paragraph.</p>
</div>

<script>
var para = document.createElement("p");
var node = document.createTextNode("This is new.");
para.appendChild(node);
var element = document.getElementById("div1");
element.appendChild(para);
console.log(element.childNodes.length);

for (var i=0; i<element.childNodes.length; i++ ) {
 console.log(element.childNodes[i].nodeType);
 console.log(element.childNodes[i].nodeName);
 console.log(element.childNodes[i].nodeValue);
}
var ele = element.childNodes[1]; //és el prime paràgraf
 console.log(ele.nodeType);
 console.log(ele.childNodes.length);
 console.log(ele.childNodes[0].nodeValue);


</script>

</body>
</html>

Exercicis

Sol i lluna

El següent codi alterna la imatge del sol i la lluna:

<!DOCTYPE html>
<html>
<body>

<p>Exemple del sol i la lluna I</p>

<img id="foto1" onclick="canviar_img1()" src="sol.png" />

<script>
function canviar_img1() {
	var str = document.getElementById("foto1").src;
    var n = str.indexOf("sol.png");
    if (n >= 0) {
	    document.getElementById("foto1").src = "lluna.png";
	} else {
	    document.getElementById("foto1").src = "sol.png";		
	}
}
</script>
</html>

Reescriu el codi anterior utiltizant el mètode addEventListener, i separa totalment el codi HTML del codi Javascript incloent el fitxer codi.js.

Solució 1:

fitxer sol_lluna2.html:

<!DOCTYPE html>
<html>
<head>
</head>
<body>

<p>Exemple del sol i la lluna II</p>

<img id="foto1" src="sol.png" />
<script type="text/javascript" src="./codi1.js"></script>
</body>
</html>

fitxer codi1.js:

var img = document.images[0];
img.addEventListener("click", function() {
    canviar_img(this);
});


function canviar_img(imatge) {
	str = imatge.src;
	//alert(str);
    var n = str.indexOf("sol.png");
    if (n >= 0) {
	    imatge.src = "lluna.png";
	} else {
	   imatge.src = "sol.png";		
	}
}

NOTA: fixar-se que si fem la inclusió del codi.js en el head, l'aplicatiu deixa de funcionar. Per què no funciona? Què hem de fer per tal de què funcioni?

Solució 2 (include de codi.js en el head) fitxer sol_lluna3.html:

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="./codi2.js"></script>
</head>
<body onload="carregar()">

	<p>Exemple del sol i la lluna II</p>
	<img id="foto1" src="sol.png" />

</body>
</html>

fitxer codi2.js:

function carregar() {
	var img = document.images[0];
	img.addEventListener("click", function() {
		 canviar_img(this);
	});
}
	
function canviar_img(imatge) {
	str = imatge.src;
	//alert(str);
    var n = str.indexOf("sol.png");
    if (n >= 0) {
	    imatge.src = "lluna.png";
	} else {
	   imatge.src = "sol.png";		
	}
}

Drag and Drop i taulell d'escacs

NOTA: ev.preventDefault(); : Cancela el evento si este es cancelable, sin detener el resto del funcionamiento del evento, es decir, puede ser llamado de nuevo.

1. Exemple mínim d'utilitzar l'event Drag and Drop (arrossegar). Per ex, moure una imatge d'una caixa a una altra.

<!DOCTYPE HTML>
<html>
<head>
<style>
#div1 {
    width: 350px;
    height: 70px;
    padding: 10px;
    border: 1px solid #aaaaaa;
}
</style>
<script>
function allowDrop(ev) {
    ev.preventDefault();
}

function drag(ev) {
    ev.dataTransfer.setData("text", ev.target.id);
}

function drop(ev) {
    ev.preventDefault();
    var data = ev.dataTransfer.getData("text");
    ev.target.appendChild(document.getElementById(data));
}
</script>
</head>
<body>

<p>Drag the W3Schools image into the rectangle:</p>

<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div>
<br>
<img id="drag1" src="img_logo.gif" draggable="true" ondragstart="drag(event)" width="336" height="69">

</body>
</html>

2. Fer un taulell d'escacs (8x8), i posicionar una dama. Moure la dama a qualsevol posició del taulell amb l'event Drag and Drop.

3. Millora: que la dama només es pugui moure a les posicions vàlides.

Exercici de classe (01/12/2017). Crear una taula des de 0

Crear una taula des de 0, crear (amb createElement) 5 files i 2 columnes, que continguin els 5 principals rius del món, i la seva longitud.

Recórrer aquesta taula que has creat, acumulant en una variable el valor de la longitud, i calcula la mitjana.

exemples:

(En el segon exemple els de w3schools estan abusant del getElementByID. És molt millor i formal el primer exemple.

crear_taula_des_de_zero.html:

<html>
<body>
<script>
var table = document.createElement('table');
for (var i = 1; i < 4; i++){
    var tr = document.createElement('tr');   

    var td1 = document.createElement('td');
    var td2 = document.createElement('td');

    var text1 = document.createTextNode('Text1');
    var text2 = document.createTextNode('Text2');

    td1.appendChild(text1);
    td2.appendChild(text2);
    tr.appendChild(td1);
    tr.appendChild(td2);

    table.appendChild(tr);
}
document.body.appendChild(table);
</script>
</body>
</html>

Exercici de classe (04/12/2017). Joc del Buscamines I (Introducció)

1. Definir una taula HTML de 8x8 caselles

2. Pintar dins les cel.les una imatge (imatge amb color gris).

3. Definir amb addeventlistener tots els events associats a canviar la imatge quan clico sobre una cel.la (bucle). Utilitzar uns id's del tipus cella00, cella01, cella02,..., cella77.

4. Important! Hem de saber distingir entre clicar el botó esquerra i el dret del ratolí. Quan clico amb l'esquerra canviar a una imatge (per ex, una imatge vermella que conté E). Quan clico amb la dreta canviar a una imatge (per ex, una imatge blava que conté D).

4. De moment res de lògica del joc.

5. Hem de separar totalment el codi HTML del codi javascript. Hem de fer servir els index i bucles, de manera que el codi seria el mateix si fem una taula 8x8 que 12x12 (o NxN).

id = "cella" + x + y


creat per Joan Quintana Compte, setembre 2018

Eines de l'usuari
Espais de noms
Variants
Accions
Navegació
Institut Jaume Balmes
Màquines recreatives
CNC
Informàtica musical
joanillo.org Planet
Eines