{"id":164067,"date":"2026-01-24T09:00:00","date_gmt":"2026-01-24T08:00:00","guid":{"rendered":"https:\/\/gtechgroup.it\/blog\/html-javascript-dom-eventi-interattivita\/"},"modified":"2026-01-24T09:00:00","modified_gmt":"2026-01-24T08:00:00","slug":"html-javascript-dom-eventi-interattivita","status":"publish","type":"post","link":"https:\/\/nuovosito.gtechgroup.it\/blog\/html-javascript-dom-eventi-interattivita\/","title":{"rendered":"HTML e JavaScript: Il DOM, gli Eventi e l&#8217;Interattivit\u00e0"},"content":{"rendered":"<p style=\"text-align: justify;\">HTML fornisce la struttura e il contenuto, CSS l&#8217;aspetto visivo, ma \u00e8 <strong>JavaScript<\/strong> che rende le pagine web interattive e dinamiche. Il ponte tra HTML e JavaScript \u00e8 il <strong>DOM (Document Object Model)<\/strong>, un&#8217;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.<\/p>\n<h2>Il DOM: Document Object Model<\/h2>\n<p style=\"text-align: justify;\">Quando il browser carica una pagina HTML, analizza il codice sorgente e costruisce una rappresentazione ad albero in memoria chiamata <strong>DOM<\/strong>. Ogni elemento HTML diventa un nodo dell&#8217;albero, con relazioni genitore-figlio che riflettono la struttura di annidamento del markup. Ad esempio, un <code>&lt;div&gt;<\/code> che contiene un <code>&lt;p&gt;<\/code> diventa un nodo genitore con un nodo figlio.<\/p>\n<p style=\"text-align: justify;\">L&#8217;oggetto <code>document<\/code> \u00e8 il punto di accesso al DOM. Tramite questo oggetto, JavaScript pu\u00f2 leggere, creare, modificare e rimuovere qualsiasi elemento della pagina. Il DOM non \u00e8 solo una rappresentazione passiva dell&#8217;HTML: \u00e8 un&#8217;interfaccia <strong>live<\/strong> \u2014 le modifiche al DOM si riflettono immediatamente nel rendering della pagina e viceversa.<\/p>\n<p style=\"text-align: justify;\">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 <strong>nodi elemento<\/strong> (Element nodes), che corrispondono ai tag HTML. Comprendere il DOM \u00e8 fondamentale per qualsiasi sviluppatore web, poich\u00e9 \u00e8 la base su cui si costruiscono tutte le interazioni front-end.<\/p>\n<h2>Accedere agli Elementi: Selettori e Query<\/h2>\n<p style=\"text-align: justify;\">JavaScript offre diversi metodi per selezionare elementi dal DOM. I pi\u00f9 utilizzati sono <code>querySelector<\/code> e <code>querySelectorAll<\/code>, che accettano qualsiasi selettore CSS valido:<\/p>\n<pre><code>\/\/ Selezionare un singolo elemento (il primo che corrisponde)\nconst titolo = document.querySelector('h1');\nconst card = document.querySelector('.card.featured');\nconst input = document.querySelector('#email');\nconst link = document.querySelector('a[href^=\"https\"]');\n\n\/\/ Selezionare tutti gli elementi corrispondenti (NodeList)\nconst paragrafi = document.querySelectorAll('p');\nconst items = document.querySelectorAll('.lista-item');\n\n\/\/ Iterare su una NodeList\nitems.forEach(item =&gt; {\n  console.log(item.textContent);\n});<\/code><\/pre>\n<p style=\"text-align: justify;\">I metodi classici come <code>getElementById<\/code>, <code>getElementsByClassName<\/code> e <code>getElementsByTagName<\/code> sono ancora disponibili e possono essere leggermente pi\u00f9 veloci in scenari specifici. La differenza principale \u00e8 che <code>getElementById<\/code> restituisce un singolo elemento, mentre i metodi <code>getElementsBy*<\/code> restituiscono <strong>HTMLCollection live<\/strong> che si aggiornano automaticamente quando il DOM cambia, a differenza della NodeList statica di querySelectorAll.<\/p>\n<p style=\"text-align: justify;\">Per navigare l&#8217;albero DOM a partire da un elemento gi\u00e0 selezionato, si possono usare le propriet\u00e0 di traversal: <code>parentElement<\/code> (elemento genitore), <code>children<\/code> (figli diretti), <code>firstElementChild<\/code>, <code>lastElementChild<\/code>, <code>nextElementSibling<\/code> e <code>previousElementSibling<\/code>. Il metodo <code>closest()<\/code> \u00e8 particolarmente utile: risale l&#8217;albero DOM fino a trovare un antenato che corrisponde a un selettore CSS specificato.<\/p>\n<h2>Modificare il Contenuto e la Struttura<\/h2>\n<p style=\"text-align: justify;\">Una volta selezionato un elemento, JavaScript pu\u00f2 modificarne il contenuto, gli attributi e lo stile. Le propriet\u00e0 pi\u00f9 utilizzate per il contenuto sono:<\/p>\n<pre><code>const elemento = document.querySelector('.messaggio');\n\n\/\/ Modificare il testo (sicuro, non interpreta HTML)\nelemento.textContent = 'Nuovo testo del messaggio';\n\n\/\/ Modificare l'HTML interno (attenzione: rischio XSS se il contenuto proviene dall'utente)\nelemento.innerHTML = '&lt;strong&gt;Testo&lt;\/strong&gt; con &lt;em&gt;formattazione&lt;\/em&gt;';\n\n\/\/ Modificare attributi\nelemento.setAttribute('data-status', 'attivo');\nelemento.id = 'messaggio-principale';\nelemento.classList.add('visibile');\nelemento.classList.remove('nascosto');\nelemento.classList.toggle('evidenziato');\n\n\/\/ Modificare stili inline\nelemento.style.color = '#ff0000';\nelemento.style.fontSize = '18px';<\/code><\/pre>\n<p style=\"text-align: justify;\">Per creare nuovi elementi e aggiungerli al DOM, si utilizza <code>document.createElement<\/code> combinato con metodi di inserimento:<\/p>\n<pre><code>\/\/ Creare un nuovo elemento\nconst nuovoParagrafo = document.createElement('p');\nnuovoParagrafo.textContent = 'Questo paragrafo \u00e8 stato creato con JavaScript';\nnuovoParagrafo.classList.add('dinamico');\n\n\/\/ Aggiungere al DOM\ndocument.querySelector('.contenitore').appendChild(nuovoParagrafo);\n\n\/\/ Inserire prima di un elemento specifico\nconst riferimento = document.querySelector('.esistente');\nriferimento.parentElement.insertBefore(nuovoParagrafo, riferimento);\n\n\/\/ Metodo moderno: insertAdjacentHTML\nelemento.insertAdjacentHTML('beforeend', '&lt;p&gt;Nuovo paragrafo&lt;\/p&gt;');\n\n\/\/ Rimuovere un elemento\nelemento.remove();<\/code><\/pre>\n<p style=\"text-align: justify;\">La differenza tra <code>textContent<\/code> e <code>innerHTML<\/code> \u00e8 cruciale per la <a href=\"https:\/\/gtechgroup.it\/blog\/sicurezza-web-html-content-security-policy\/\">sicurezza<\/a>: textContent inserisce testo puro (i tag HTML vengono visualizzati come testo), mentre innerHTML interpreta il markup HTML. Se il contenuto proviene dall&#8217;utente, usare innerHTML senza sanitizzazione \u00e8 un vettore di attacco XSS.<\/p>\n<h2>Eventi: Rendere la Pagina Interattiva<\/h2>\n<p style=\"text-align: justify;\">Gli <strong>eventi<\/strong> sono il meccanismo con cui JavaScript risponde alle azioni dell&#8217;utente e ai cambiamenti della pagina. Il metodo standard per gestire gli eventi \u00e8 <code>addEventListener<\/code>:<\/p>\n<pre><code>const pulsante = document.querySelector('#inviaForm');\n\n\/\/ Evento click\npulsante.addEventListener('click', function(event) {\n  event.preventDefault(); \/\/ Previene il comportamento default\n  console.log('Pulsante cliccato!');\n});\n\n\/\/ Evento submit su un form\nconst form = document.querySelector('form');\nform.addEventListener('submit', function(event) {\n  event.preventDefault();\n  const dati = new FormData(form);\n  console.log('Nome:', dati.get('nome'));\n});\n\n\/\/ Evento input (si attiva ad ogni modifica)\nconst campo = document.querySelector('#ricerca');\ncampo.addEventListener('input', function(event) {\n  console.log('Valore attuale:', event.target.value);\n});\n\n\/\/ Evento keydown\ndocument.addEventListener('keydown', function(event) {\n  if (event.key === 'Escape') {\n    chiudiModale();\n  }\n});<\/code><\/pre>\n<p style=\"text-align: justify;\">Gli eventi pi\u00f9 utilizzati includono: <code>click<\/code> (click del mouse o tap), <code>submit<\/code> (invio di un form), <code>input<\/code> (modifica di un campo), <code>change<\/code> (valore finale di un campo dopo il blur), <code>keydown<\/code>\/<code>keyup<\/code> (tasti della tastiera), <code>focus<\/code>\/<code>blur<\/code> (focus su un elemento), <code>scroll<\/code> (scroll della pagina), <code>resize<\/code> (ridimensionamento della finestra) e <code>load<\/code> (caricamento completo della risorsa).<\/p>\n<h2>Event Delegation, Bubbling e Data Attributes<\/h2>\n<p style=\"text-align: justify;\">L&#8217;<strong>event bubbling<\/strong> \u00e8 il meccanismo per cui un evento generato su un elemento risale (bubble up) attraverso tutti i suoi antenati fino al <code>&lt;document&gt;<\/code>. Questo meccanismo \u00e8 alla base dell&#8217;<strong>event delegation<\/strong>, una tecnica potente e performante per gestire eventi su molti elementi.<\/p>\n<p style=\"text-align: justify;\">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:<\/p>\n<pre><code>&lt;ul id=\"lista-prodotti\"&gt;\n  &lt;li data-id=\"1\" data-prezzo=\"29.99\"&gt;Prodotto A&lt;\/li&gt;\n  &lt;li data-id=\"2\" data-prezzo=\"49.99\"&gt;Prodotto B&lt;\/li&gt;\n  &lt;li data-id=\"3\" data-prezzo=\"19.99\"&gt;Prodotto C&lt;\/li&gt;\n&lt;\/ul&gt;\n\n&lt;script&gt;\ndocument.getElementById('lista-prodotti').addEventListener('click', function(event) {\n  const item = event.target.closest('li');\n  if (!item) return;\n\n  const id = item.dataset.id;\n  const prezzo = item.dataset.prezzo;\n  console.log('Selezionato prodotto', id, 'al prezzo di', prezzo);\n});\n&lt;\/script&gt;<\/code><\/pre>\n<p style=\"text-align: justify;\">I <strong>data attributes<\/strong> (<code>data-*<\/code>) sono attributi HTML personalizzati che permettono di associare dati arbitrari agli elementi. In JavaScript, si accede ad essi tramite la propriet\u00e0 <code>dataset<\/code> dell&#8217;elemento. L&#8217;attributo <code>data-prezzo=\"29.99\"<\/code> diventa <code>element.dataset.prezzo<\/code> in JavaScript (il prefisso <code>data-<\/code> viene rimosso e il nome viene convertito in camelCase).<\/p>\n<p style=\"text-align: justify;\">Infine, \u00e8 importante comprendere la differenza tra <code>DOMContentLoaded<\/code> e <code>load<\/code>: <strong>DOMContentLoaded<\/strong> si attiva quando l&#8217;HTML \u00e8 stato completamente analizzato e il DOM \u00e8 pronto, senza attendere immagini, fogli di stile e iframe. <strong>load<\/strong> si attiva quando tutte le risorse della pagina sono state scaricate. Per la maggior parte degli script che manipolano il DOM, DOMContentLoaded \u00e8 il momento giusto per iniziare, oppure si pu\u00f2 posizionare il tag <code>&lt;script&gt;<\/code> alla fine del <code>&lt;body&gt;<\/code> o utilizzare l&#8217;attributo <code>defer<\/code>.<\/p>\n<p style=\"text-align: justify;\">Hai bisogno di aiuto con l&#8217;interattivit\u00e0 del tuo sito web? <strong>G Tech Group<\/strong> offre servizi di sviluppo web professionale e consulenza tecnica. Contattaci a <strong>support@gtechgroup.it<\/strong> o via WhatsApp al <strong>0465 84 62 45<\/strong>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>HTML fornisce la struttura e il contenuto, CSS l&#8217;aspetto visivo, ma \u00e8 JavaScript che rende le pagine web interattive e dinamiche. Il ponte tra HTML&hellip;<\/p>\n","protected":false},"author":2,"featured_media":164247,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1246],"tags":[787],"class_list":["post-164067","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-html","tag-sviluppo-web"],"_links":{"self":[{"href":"https:\/\/nuovosito.gtechgroup.it\/blog\/wp-json\/wp\/v2\/posts\/164067","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/nuovosito.gtechgroup.it\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/nuovosito.gtechgroup.it\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/nuovosito.gtechgroup.it\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/nuovosito.gtechgroup.it\/blog\/wp-json\/wp\/v2\/comments?post=164067"}],"version-history":[{"count":0,"href":"https:\/\/nuovosito.gtechgroup.it\/blog\/wp-json\/wp\/v2\/posts\/164067\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/nuovosito.gtechgroup.it\/blog\/wp-json\/wp\/v2\/media\/164247"}],"wp:attachment":[{"href":"https:\/\/nuovosito.gtechgroup.it\/blog\/wp-json\/wp\/v2\/media?parent=164067"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/nuovosito.gtechgroup.it\/blog\/wp-json\/wp\/v2\/categories?post=164067"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/nuovosito.gtechgroup.it\/blog\/wp-json\/wp\/v2\/tags?post=164067"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}