DOM: Model de Document
Qué és el DOM?
El DOM (Document Object Model) és una representació en forma d'arbre de tots els elements d'un document HTML. JavaScript pot accedir a qualsevol node d'aquest arbre i llegir, crear, modificar o eliminar elements dinàmicament.
document
└── html
├── head
│ ├── meta
│ └── title
└── body
├── header
│ └── h1
├── main
│ ├── article
│ │ ├── h2
│ │ └── p
│ └── aside
└── footer
Selecció d'elements
// Per ID (retorna un element o null)
const titol = document.getElementById('titol-principal');
// Per classe (retorna HTMLCollection)
const targetes = document.getElementsByClassName('targeta');
// Per etiqueta (retorna HTMLCollection)
const paràgrafs = document.getElementsByTagName('p');
// querySelector — primer element que coincideix (CSS selector)
const primer = document.querySelector('.targeta');
const nav = document.querySelector('nav > a:first-child');
// querySelectorAll — tots els elements que coincideixen (NodeList)
const totes = document.querySelectorAll('.targeta');
const inputs = document.querySelectorAll('input[type="text"]');
// Iterar NodeList
totes.forEach(targeta => {
console.log(targeta.textContent);
});
Llegir i modificar contingut
const elem = document.querySelector('#missatge');
// Llegir contingut
console.log(elem.textContent); // text pla (sense HTML)
console.log(elem.innerHTML); // HTML intern (permet HTML)
console.log(elem.outerHTML); // HTML de l'element i els seus fills
// Modificar contingut
elem.textContent = "Nou text"; // text pla (segur)
elem.innerHTML = "<strong>Text en negreta</strong>"; // HTML (cuidado XSS)
// Atributs
const img = document.querySelector('img');
console.log(img.getAttribute('alt')); // llegir atribut
img.setAttribute('alt', 'Nova descripció'); // modificar atribut
img.removeAttribute('title'); // eliminar atribut
// Propietats directes (recomanat per a atributs comuns)
const input = document.querySelector('input');
console.log(input.value); // valor actual
console.log(input.checked); // per a checkboxes
input.disabled = true; // desactivar
// Dataset (atributs data-*)
// HTML: <div data-id="42" data-nom="Joan">
const div = document.querySelector('[data-id]');
console.log(div.dataset.id); // "42"
console.log(div.dataset.nom); // "Joan"
div.dataset.edat = 22; // afegir data-edat="22"
Modificar estils
const elem = document.querySelector('.targeta');
// Estils en línia (inline)
elem.style.color = '#00695c';
elem.style.fontSize = '1.2rem';
elem.style.display = 'none'; // amagar
elem.style.display = 'block'; // mostrar
// Classes CSS (recomanat — separa JS del CSS)
elem.classList.add('actiu'); // afegir classe
elem.classList.remove('actiu'); // eliminar classe
elem.classList.toggle('actiu'); // alternar (add si no existeix, remove si existeix)
elem.classList.contains('actiu'); // comprova si té la classe (retorna boolean)
elem.classList.replace('vell', 'nou'); // reemplaça una classe
// Llegir estils computats (estils aplicats per CSS)
const estils = window.getComputedStyle(elem);
console.log(estils.color);
console.log(estils.fontSize);
Crear i inserir elements
// Crear un element
const nouParagraf = document.createElement('p');
nouParagraf.textContent = 'Un nou paràgraf';
nouParagraf.classList.add('intro');
// Inserir al DOM
const contenidor = document.querySelector('#contingut');
contenidor.appendChild(nouParagraf); // al final
contenidor.prepend(nouParagraf); // al principi
contenidor.insertBefore(nouParagraf, ref); // davant d'un element de referència
// Mètodes moderns (ES2017+)
contenidor.append(nouParagraf); // al final (accepta strings)
contenidor.prepend(nouParagraf); // al principi
ref.before(nouParagraf); // davant de ref
ref.after(nouParagraf); // darrere de ref
// Clonar elements
const copia = elem.cloneNode(true); // true = clonar fills també
contenidor.appendChild(copia);
// Crear elements complexos amb template literal
const html = `
<article class="targeta" data-id="${id}">
<h3>${titol}</h3>
<p>${descripcio}</p>
</article>
`;
contenidor.insertAdjacentHTML('beforeend', html);
Eliminar elements
// Mètode modern (recomanat)
const elem = document.querySelector('.temp');
elem.remove();
// Mètode antic (via pare)
elem.parentNode.removeChild(elem);
// Buidar el contingut d'un element
const llista = document.querySelector('#llista');
llista.innerHTML = ''; // ràpid però destrueix els event listeners fills
while (llista.firstChild) { // net i segur
llista.removeChild(llista.firstChild);
}
Events
// addEventListener (recomanat)
const botó = document.querySelector('#enviar');
botó.addEventListener('click', function(event) {
console.log('S\'ha fet clic!');
event.preventDefault(); // evita el comportament per defecte (enviar form, seguir link)
event.stopPropagation(); // evita que l'event es propagui cap amunt (bubbling)
});
// Arrow function
botó.addEventListener('click', (e) => {
console.log(e.target); // l'element que ha generat l'event
console.log(e.currentTarget); // l'element al qual s'ha afegit el listener
});
// Events de formulari
const form = document.querySelector('#el-meu-form');
form.addEventListener('submit', (e) => {
e.preventDefault();
const nom = document.querySelector('#nom').value;
if (!nom) {
alert('El nom és obligatori!');
return;
}
console.log('Formulari enviat amb nom:', nom);
});
// Event de canvi d'input
document.querySelector('#nota').addEventListener('input', (e) => {
const valor = parseFloat(e.target.value);
const resultat = document.querySelector('#resultat');
resultat.textContent = valor >= 5 ? 'Aprovat' : 'Suspens';
});
// Events de teclat
document.addEventListener('keydown', (e) => {
console.log(e.key, e.code, e.ctrlKey, e.shiftKey);
if (e.key === 'Enter') { /* ... */ }
if (e.ctrlKey && e.key === 's') {
e.preventDefault();
console.log('Ctrl+S atrapat!');
}
});
// Event delegation (per a elements dinàmics)
document.querySelector('#llista').addEventListener('click', (e) => {
const item = e.target.closest('li');
if (item) {
item.classList.toggle('completat');
}
});
Miniactivitat AC03737
Crea una pàgina HTML amb:
1. Una llista de tasques (<ul>) buida
2. Un camp de text i un botó "Afegir"
3. Quan es clica el botó, afegeix un <li> a la llista amb el text del camp
4. Cada <li> ha de tenir un botó "Eliminar" que l'elimini
5. En fer clic a un <li> (però no al seu botó), es marca/desmarca com a completada (class completada)