JavaScript - Selezionare elementi del DOM
Impara a selezionare elementi del DOM in JavaScript con getElementById, querySelector, querySelectorAll, getElementsByClassName, matches e closest — con esempi e quando usare ciascun metodo.
Prima di poter modificare qualcosa su una pagina con JavaScript — aggiornare il testo, attivare una classe, associare un gestore di clic — devi prima trovare l'elemento che ti serve. Questo atto di ricerca si chiama selezione di un elemento del DOM. Questo capitolo copre ogni metodo disponibile, spiega cosa restituisce ciascuno e mostra quando utilizzare quale.
Cosa significa "selezionare un elemento"
Il Document Object Model (DOM) è la rappresentazione live del browser, a forma di albero, del tuo HTML. Ogni tag diventa un oggetto nodo che puoi leggere e modificare tramite JavaScript. La selezione è il processo di individuazione di uno o più di questi nodi, in modo da poter mantenere un riferimento ad essi in una variabile:
const heading = document.querySelector('h1');
// `heading` now points at the real <h1> on the page.Una volta ottenuto quel riferimento, tutto il resto — leggere attributi e proprietà, modificare gli stili, aggiungere listener di eventi — funziona su di esso.
I metodi di selezione si dividono in due gruppi:
- Ricerche per ID / classe / tag — veloci, restituiscono collezioni live (tranne
getElementById). - Ricerche con selettori CSS (
querySelector,querySelectorAll) — flessibili, accettano qualsiasi selettore CSS, restituiscono un risultato statico.
Selezionare un elemento per ID: getElementById
Il modo più rapido per recuperare un singolo elemento è tramite il suo id univoco. Restituisce l'elemento, oppure null se non esiste nessun elemento con quell'ID.
const element = document.getElementById('example');
element.textContent = 'You selected the element by its ID!';Poiché gli ID devono essere univoci, getElementById restituisce un singolo elemento (non una collezione) ed è la ricerca più diretta e performante.
Se nessun elemento corrisponde, getElementById restituisce null. Accedere a una proprietà su null genera TypeError: Cannot read properties of null. Proteggi il codice con: const el = document.getElementById('maybe'); if (el) { /* ... */ }.
Selezionare per nome di classe: getElementsByClassName
Questo metodo restituisce una HTMLCollection live di tutti gli elementi che hanno la classe specificata. "Live" significa che la collezione si aggiorna automaticamente quando il DOM cambia.
const elements = document.getElementsByClassName('example');
Array.from(elements).forEach((element, index) => {
element.textContent = `Element ${index + 1} changed!`;
});Un HTMLCollection è simile a un array ma non è un array vero e proprio, quindi non ha forEach/map. Convertila con Array.from() (o con lo spread [...elements]) prima di usare i metodi degli array.
Poiché la collezione è live, iterare con for (let i = 0; i < c.length; i++) rimuovendo elementi corrispondenti può saltarne alcuni — la lunghezza si riduce durante l'iterazione. Crea prima uno snapshot con Array.from() quando prevedi di mutare il DOM durante il ciclo.
Selezionare per nome di tag: getElementsByTagName
Seleziona tutti gli elementi con un determinato nome di tag e restituisce una HTMLCollection live.
const paragraphs = document.getElementsByTagName('p');
for (let i = 0; i < paragraphs.length; i++) {
paragraphs[i].style.backgroundColor = 'yellow';
}Passa '*' per trovare tutti gli elementi della pagina. È utile quando vuoi operare su tutti i tag di un certo tipo, ad esempio evidenziare ogni paragrafo.
Selezionare per attributo name: getElementsByName
Restituisce una NodeList live degli elementi che condividono lo stesso attributo name. È particolarmente utile per i controlli di modulo — ad esempio, tutti i radio button di un gruppo:
const options = document.getElementsByName('plan');
options.forEach((radio) => {
radio.addEventListener('change', () => {
console.log('Selected plan:', radio.value);
});
});Per una gestione più approfondita dei moduli, vedi lavorare con i moduli nel DOM.
Selezionare con selettori CSS: querySelector
querySelector restituisce il primo elemento che corrisponde a qualsiasi selettore CSS passato, oppure null se non trova corrispondenze. È il metodo più versatile per selezionare un singolo elemento.
const element = document.querySelector('.example');
element.style.backgroundColor = 'lightblue';Poiché accetta la sintassi completa dei selettori CSS, puoi selezionare in profondità: querySelector('nav ul li.active a') trova il primo link corrispondente senza concatenare più chiamate.
Selezionare tutte le corrispondenze: querySelectorAll
Restituisce una NodeList statica di tutti gli elementi che corrispondono al selettore. A differenza di getElementsBy..., questo snapshot non si aggiorna quando il DOM cambia successivamente.
const elements = document.querySelectorAll('.example');
elements.forEach((element, index) => {
element.style.backgroundColor = 'lightgreen';
element.textContent = `Element ${index + 1} highlighted!`;
});Una NodeList ha un metodo forEach nativo, quindi puoi iterarla direttamente. Per usare map/filter, convertila prima con Array.from(elements).
querySelectorAll restituisce una NodeList statica — non rifletterà elementi aggiunti o rimossi in seguito. getElementsByClassName e getElementsByTagName restituiscono HTMLCollection live che invece lo fanno. Scegli la versione statica quando vuoi uno snapshot stabile, quella live quando vuoi che la collezione segua il DOM.
Limitare una ricerca a un elemento
Tutti i metodi querySelector* e getElementsBy* esistono anche sui singoli elementi, non solo su document. Chiamarli su un elemento restringe la ricerca ai suoi discendenti:
const card = document.querySelector('.card');
const title = card.querySelector('.title'); // only inside .cardLimitare l'ambito mantiene le query veloci ed evita di selezionare accidentalmente elementi in altre parti della pagina.
Testare un elemento: matches
matches non restituisce un elemento — restituisce true/false per indicare se un determinato elemento corrisponde a un selettore CSS. È ideale all'interno di gestori di eventi e per la delegazione degli eventi.
const element = document.getElementById('test');
if (element.matches('.example')) {
element.style.color = 'red';
element.textContent = 'Element matches the selector!';
}Risalire l'albero: closest
closest parte dall'elemento stesso e risale attraverso i suoi antenati, restituendo il più vicino che corrisponde al selettore (oppure null). È il modo più pulito per trovare un elemento contenitore.
const element = document.getElementById('child');
const parent = element.closest('.outer');
parent.style.border = '2px solid red';matches + closest sono la base della delegazione degli eventi: associa un solo listener a un contenitore, poi nel gestore usa event.target.closest('.item') per capire quale elemento figlio è stato effettivamente cliccato. Scopri di più in gestione degli eventi nel DOM.
Combinare selettori per una selezione precisa
I selettori CSS si compongono, quindi puoi essere preciso quanto necessario senza codice aggiuntivo:
const element = document.querySelector('.example.special');
element.style.backgroundColor = 'pink';
element.textContent = 'Special element highlighted!';Qui .example.special corrisponde a un elemento che ha entrambe le classi. Puoi concatenare combinatori (>, spazio per i discendenti, +, ~), selettori di attributo (input[type="email"]) e pseudo-classi (li:first-child).
Quale metodo devo usare?
| Metodo | Restituisce | Live? | Ideale per |
|---|---|---|---|
getElementById | singolo elemento / null | n/a | un elemento con un ID univoco noto |
getElementsByClassName | HTMLCollection | live | tutti gli elementi di una classe, seguendo il DOM |
getElementsByTagName | HTMLCollection | live | tutti gli elementi di un tag |
getElementsByName | NodeList | live | controlli di modulo con lo stesso name |
querySelector | prima corrispondenza / null | n/a | primo elemento che corrisponde a qualsiasi selettore CSS |
querySelectorAll | NodeList | static | uno snapshot stabile di tutte le corrispondenze |
matches | boolean | n/a | verificare se un elemento corrisponde a un selettore |
closest | antenato più vicino / null | n/a | trovare un elemento contenitore |
Regole pratiche:
- Usa
querySelector/querySelectorAllper impostazione predefinita — un'API coerente con la piena potenza dei selettori CSS. - Usa
getElementByIdquando hai un ID univoco e vuoi la ricerca più veloce possibile. - Usa una collezione live (
getElementsBy...) solo quando vuoi specificamente che segua le modifiche del DOM; altrimenti preferisci ilquerySelectorAllstatico.
Errori comuni
- Risultati
null.getElementById,querySelectoreclosestrestituiscono tuttinullquando non c'è corrispondenza. Controlla sempre prima di usare il risultato. - Esecuzione prima che il DOM esista. Se lo script viene eseguito nel
<head>prima che gli elementi siano stati analizzati, le selezioni non restituiscono nulla. Metti gli script alla fine del<body>, usadefer, o attendiDOMContentLoaded. - Le collezioni non sono array.
HTMLCollectionnon haforEach.NodeListhaforEachma nonmap/filter. Converti conArray.from()in caso di dubbio.
Conclusione
Selezionare gli elementi è il punto di ingresso per ogni operazione sul DOM. Per la maggior parte del codice, querySelector e querySelectorAll offrono un'API flessibile e basata sui selettori CSS; getElementById rimane la scelta più veloce per gli ID univoci; e matches / closest alimentano una delegazione degli eventi pulita. Una volta che sai selezionare gli elementi in modo affidabile, continua con la manipolazione del DOM e la navigazione nel DOM.
Nota sulle prestazioni: tutti questi metodi sono sufficientemente veloci per le pagine tipiche. Il costo reale deriva dall'eseguirli ripetutamente in cicli stretti — salva la selezione in una variabile invece di eseguire nuovamente la query. Le NodeList statiche di querySelectorAll evitano il bookkeeping del reflow che mantiene aggiornate le HTMLCollection live.