Chi Siamo Area Clienti Promo del Mese Dicono di Noi Portfolio FAQ Blog
HTML

HTML e JavaScript: Il DOM, gli Eventi e l’Interattività

Gianluca Gentile
Gianluca Gentile
· 6 min di lettura

HTML fornisce la struttura e il contenuto, CSS l’aspetto visivo, ma è JavaScript che rende le pagine web interattive e dinamiche. Il ponte tra HTML e JavaScript è il DOM (Document Object Model), un’interfaccia di programmazione che rappresenta il documento HTML come un albero di oggetti manipolabili. In questa guida esploreremo come JavaScript accede, modifica e interagisce con gli elementi HTML, dalle operazioni base alle tecniche avanzate.

Il DOM: Document Object Model

Quando il browser carica una pagina HTML, analizza il codice sorgente e costruisce una rappresentazione ad albero in memoria chiamata DOM. Ogni elemento HTML diventa un nodo dell’albero, con relazioni genitore-figlio che riflettono la struttura di annidamento del markup. Ad esempio, un <div> che contiene un <p> diventa un nodo genitore con un nodo figlio.

L’oggetto document è il punto di accesso al DOM. Tramite questo oggetto, JavaScript può leggere, creare, modificare e rimuovere qualsiasi elemento della pagina. Il DOM non è solo una rappresentazione passiva dell’HTML: è un’interfaccia live — le modifiche al DOM si riflettono immediatamente nel rendering della pagina e viceversa.

Il DOM include non solo gli elementi HTML ma anche i nodi di testo, i commenti e gli attributi. Tuttavia, nella pratica quotidiana, la maggior parte delle operazioni riguarda i nodi elemento (Element nodes), che corrispondono ai tag HTML. Comprendere il DOM è fondamentale per qualsiasi sviluppatore web, poiché è la base su cui si costruiscono tutte le interazioni front-end.

Accedere agli Elementi: Selettori e Query

JavaScript offre diversi metodi per selezionare elementi dal DOM. I più utilizzati sono querySelector e querySelectorAll, che accettano qualsiasi selettore CSS valido:

// Selezionare un singolo elemento (il primo che corrisponde)
const titolo = document.querySelector('h1');
const card = document.querySelector('.card.featured');
const input = document.querySelector('#email');
const link = document.querySelector('a[href^="https"]');

// Selezionare tutti gli elementi corrispondenti (NodeList)
const paragrafi = document.querySelectorAll('p');
const items = document.querySelectorAll('.lista-item');

// Iterare su una NodeList
items.forEach(item => {
  console.log(item.textContent);
});

I metodi classici come getElementById, getElementsByClassName e getElementsByTagName sono ancora disponibili e possono essere leggermente più veloci in scenari specifici. La differenza principale è che getElementById restituisce un singolo elemento, mentre i metodi getElementsBy* restituiscono HTMLCollection live che si aggiornano automaticamente quando il DOM cambia, a differenza della NodeList statica di querySelectorAll.

Per navigare l’albero DOM a partire da un elemento già selezionato, si possono usare le proprietà di traversal: parentElement (elemento genitore), children (figli diretti), firstElementChild, lastElementChild, nextElementSibling e previousElementSibling. Il metodo closest() è particolarmente utile: risale l’albero DOM fino a trovare un antenato che corrisponde a un selettore CSS specificato.

Modificare il Contenuto e la Struttura

Una volta selezionato un elemento, JavaScript può modificarne il contenuto, gli attributi e lo stile. Le proprietà più utilizzate per il contenuto sono:

const elemento = document.querySelector('.messaggio');

// Modificare il testo (sicuro, non interpreta HTML)
elemento.textContent = 'Nuovo testo del messaggio';

// Modificare l'HTML interno (attenzione: rischio XSS se il contenuto proviene dall'utente)
elemento.innerHTML = '<strong>Testo</strong> con <em>formattazione</em>';

// Modificare attributi
elemento.setAttribute('data-status', 'attivo');
elemento.id = 'messaggio-principale';
elemento.classList.add('visibile');
elemento.classList.remove('nascosto');
elemento.classList.toggle('evidenziato');

// Modificare stili inline
elemento.style.color = '#ff0000';
elemento.style.fontSize = '18px';

Per creare nuovi elementi e aggiungerli al DOM, si utilizza document.createElement combinato con metodi di inserimento:

// Creare un nuovo elemento
const nuovoParagrafo = document.createElement('p');
nuovoParagrafo.textContent = 'Questo paragrafo è stato creato con JavaScript';
nuovoParagrafo.classList.add('dinamico');

// Aggiungere al DOM
document.querySelector('.contenitore').appendChild(nuovoParagrafo);

// Inserire prima di un elemento specifico
const riferimento = document.querySelector('.esistente');
riferimento.parentElement.insertBefore(nuovoParagrafo, riferimento);

// Metodo moderno: insertAdjacentHTML
elemento.insertAdjacentHTML('beforeend', '<p>Nuovo paragrafo</p>');

// Rimuovere un elemento
elemento.remove();

La differenza tra textContent e innerHTML è cruciale per la sicurezza: textContent inserisce testo puro (i tag HTML vengono visualizzati come testo), mentre innerHTML interpreta il markup HTML. Se il contenuto proviene dall’utente, usare innerHTML senza sanitizzazione è un vettore di attacco XSS.

Eventi: Rendere la Pagina Interattiva

Gli eventi sono il meccanismo con cui JavaScript risponde alle azioni dell’utente e ai cambiamenti della pagina. Il metodo standard per gestire gli eventi è addEventListener:

const pulsante = document.querySelector('#inviaForm');

// Evento click
pulsante.addEventListener('click', function(event) {
  event.preventDefault(); // Previene il comportamento default
  console.log('Pulsante cliccato!');
});

// Evento submit su un form
const form = document.querySelector('form');
form.addEventListener('submit', function(event) {
  event.preventDefault();
  const dati = new FormData(form);
  console.log('Nome:', dati.get('nome'));
});

// Evento input (si attiva ad ogni modifica)
const campo = document.querySelector('#ricerca');
campo.addEventListener('input', function(event) {
  console.log('Valore attuale:', event.target.value);
});

// Evento keydown
document.addEventListener('keydown', function(event) {
  if (event.key === 'Escape') {
    chiudiModale();
  }
});

Gli eventi più utilizzati includono: click (click del mouse o tap), submit (invio di un form), input (modifica di un campo), change (valore finale di un campo dopo il blur), keydown/keyup (tasti della tastiera), focus/blur (focus su un elemento), scroll (scroll della pagina), resize (ridimensionamento della finestra) e load (caricamento completo della risorsa).

Event Delegation, Bubbling e Data Attributes

L’event bubbling è il meccanismo per cui un evento generato su un elemento risale (bubble up) attraverso tutti i suoi antenati fino al <document>. Questo meccanismo è alla base dell’event delegation, una tecnica potente e performante per gestire eventi su molti elementi.

Invece di aggiungere un event listener a ogni elemento di una lista (che potrebbe contenere centinaia di items), si aggiunge un singolo listener al contenitore:

<ul id="lista-prodotti">
  <li data-id="1" data-prezzo="29.99">Prodotto A</li>
  <li data-id="2" data-prezzo="49.99">Prodotto B</li>
  <li data-id="3" data-prezzo="19.99">Prodotto C</li>
</ul>

<script>
document.getElementById('lista-prodotti').addEventListener('click', function(event) {
  const item = event.target.closest('li');
  if (!item) return;

  const id = item.dataset.id;
  const prezzo = item.dataset.prezzo;
  console.log('Selezionato prodotto', id, 'al prezzo di', prezzo);
});
</script>

I data attributes (data-*) sono attributi HTML personalizzati che permettono di associare dati arbitrari agli elementi. In JavaScript, si accede ad essi tramite la proprietà dataset dell’elemento. L’attributo data-prezzo="29.99" diventa element.dataset.prezzo in JavaScript (il prefisso data- viene rimosso e il nome viene convertito in camelCase).

Infine, è importante comprendere la differenza tra DOMContentLoaded e load: DOMContentLoaded si attiva quando l’HTML è stato completamente analizzato e il DOM è pronto, senza attendere immagini, fogli di stile e iframe. load si attiva quando tutte le risorse della pagina sono state scaricate. Per la maggior parte degli script che manipolano il DOM, DOMContentLoaded è il momento giusto per iniziare, oppure si può posizionare il tag <script> alla fine del <body> o utilizzare l’attributo defer.

Hai bisogno di aiuto con l’interattività del tuo sito web? G Tech Group offre servizi di sviluppo web professionale e consulenza tecnica. Contattaci a su*****@********up.it o via WhatsApp al 0465 84 62 45.

#sviluppo web