Selezionare elementi del DOM in modo robusto con <strong>data-attributes</strong>

by Anastasia P.
SHARE
Selezionare elementi del DOM in modo robusto con <strong>data-attributes</strong>
© Guida-HTML5.it

Introduzione

Quando si lavora con il DOM in JavaScript, il problema non è solo trovare un elemento, ma farlo in modo stabile, leggibile e manutenibile. In molti progetti, soprattutto quando l’interfaccia cresce, affidarsi a classi CSS o a strutture HTML troppo specifiche rende il codice fragile: basta cambiare un nome di classe o spostare un nodo per rompere la logica JavaScript.

Un approccio molto utile, pratico e spesso sottovalutato è l’uso degli attributi personalizzati, in particolare i data-attributes come data-action, data-id o data-role. Questi attributi permettono di selezionare gli elementi in base al loro significato funzionale, separando in modo chiaro la logica JavaScript dalla presentazione CSS.

In questo tutorial vedremo come usare i data-attributes per selezionare e manipolare elementi del DOM in modo più robusto, con un esempio reale: una piccola dashboard con schede prodotto, pulsanti di azione e un pannello informativo aggiornato dinamicamente.

Codice completo

<div class="catalogo">
  <article class="card" data-product-id="101">
    <h3>Taccuino tecnico</h3>
    <p>Formato A5, copertina rigida.</p>
    <button data-action="show-details">Dettagli</button>
    <button data-action="add-to-cart">Aggiungi al carrello</button>
  </article>

  <article class="card" data-product-id="102">
    <h3>Mouse wireless</h3>
    <p>Silenzioso e ricaricabile via USB-C.</p>
    <button data-action="show-details">Dettagli</button>
    <button data-action="add-to-cart">Aggiungi al carrello</button>
  </article>
</div>

<aside class="pannello" data-panel="info">
  <h2>Informazioni prodotto</h2>
  <p data-field="message">Seleziona un prodotto per vedere i dettagli.</p>
</aside>

<script>
  // Dati di esempio: in un´app reale potrebbero arrivare da API
  const products = {
    101: {
      name: "Taccuino tecnico",
      description: "Formato A5, copertina rigida, 192 pagine.",
      price: 9.99
    },
    102: {
      name: "Mouse wireless",
      description: "Mouse ergonomico, silenzioso e ricaricabile via USB-C.",
      price: 24.5
    }
  };

  // Selezioniamo il contenitore principale
  const catalogo = document.querySelector(".catalogo");

  // Selezioniamo il pannello informativo e il campo messaggio
  const pannelloInfo = document.querySelector(´[data-panel="info"]´);
  const messageField = document.querySelector(´[data-field="message"]´);

  // Event delegation: ascoltiamo i click sul contenitore,
  // così gestiamo anche eventuali elementi aggiunti in futuro
  catalogo.addEventListener("click", (event) => {
    const button = event.target.closest("button[data-action]");

    // Se il click non arriva da un pulsante valido, interrompiamo
    if (!button) return;

    // Troviamo la scheda prodotto più vicina
    const card = button.closest("[data-product-id]");
    if (!card) return;

    const productId = card.dataset.productId;
    const action = button.dataset.action;
    const product = products[productId];

    if (!product) {
      messageField.textContent = "Prodotto non trovato.";
      return;
    }

    if (action === "show-details") {
      messageField.innerHTML = `
        <strong>${product.name}</strong><br>
        ${product.description}<br>
        Prezzo: €${product.price.toFixed(2)}
      `;
      pannelloInfo.setAttribute("data-state", "visible");
    }

    if (action === "add-to-cart") {
      messageField.textContent = `${product.name} aggiunto al carrello.`;
      pannelloInfo.setAttribute("data-state", "success");
    }
  });

  // Funzione utile: selezione sicura di un elemento per data-attribute
  function getByData(selector, value) {
    return document.querySelector(`[data-${selector}="${value}"]`);
  }

  // Esempio di utilizzo della funzione
  const infoPanel = getByData("panel", "info");
  console.log("Pannello trovato:", infoPanel);
</script>

Spiegazione

Il punto forte di questo approccio è semplice: il JavaScript non dipende dall’aspetto grafico. Le classi CSS possono cambiare per esigenze di design, ma i data-attributes possono restare stabili perché rappresentano il ruolo funzionale di un elemento.

1. Cosa sono i data-attributes

I data-attributes sono attributi HTML personalizzati che iniziano con data-. Esempi:

  • data-product-id="101": identifica un prodotto.
  • data-action="add-to-cart": indica l’azione associata a un pulsante.
  • data-panel="info": identifica una sezione della pagina.

In JavaScript puoi leggerli comodamente con element.dataset. Ad esempio, data-product-id diventa element.dataset.productId.

2. Selezione mirata con querySelector

Nel codice usiamo selettori come [data-panel="info"] o button[data-action]. Questo ci permette di prendere esattamente gli elementi che ci servono, senza dipendere da strutture troppo rigide.

È una soluzione molto utile quando:

  • hai molti componenti simili nella stessa pagina;
  • vuoi distinguere tra logica e stile;
  • stai costruendo interfacce dinamiche o componenti riutilizzabili.

3. Event delegation per elementi dinamici

Invece di assegnare un listener a ogni pulsante, ascoltiamo il click sul contenitore .catalogo. Poi, con event.target.closest("button[data-action]"), risaliamo al pulsante effettivamente cliccato.

Questo è fondamentale per la manutenzione: se in futuro aggiungi nuove card al DOM, non devi registrare nuovi event listener. Il comportamento continua a funzionare automaticamente.

4. Uso di closest per trovare il contesto

Quando premi un pulsante, ci interessa sapere a quale prodotto appartiene. Per farlo usiamo closest("[data-product-id]"), che risale il DOM fino a trovare l’elemento più vicino con quell’attributo.

Questo evita di dipendere da livelli annidati specifici. Se domani aggiungi un wrapper interno al bottone, il codice continuerà a funzionare.

5. Manipolazione del contenuto

Nel pannello informativo aggiorniamo il testo con textContent oppure, quando serve formattazione, con innerHTML. In questo esempio, per mostrare il dettaglio prodotto, usiamo innerHTML perché vogliamo andare a capo e mettere in evidenza il nome.

Attenzione però: innerHTML va usato con cautela. Se i contenuti provengono dall’utente o da fonti non fidate, bisogna sanificarli per evitare problemi di sicurezza.

6. Una funzione riutilizzabile per selezionare elementi

La funzione getByData() è un piccolo helper che rende più leggibile la selezione di elementi tramite data-attributes. È utile in progetti medi o grandi, dove ripetere selettori complessi può diventare rumoroso.

Non è obbligatoria, ma aiuta a centralizzare lo stile di selezione e a mantenere il codice più coerente.

Best practice

  • Usa i data-attributes per la logica, non per lo stile: le classi CSS servono al design, i data-attributes al comportamento.
  • Preferisci nomi chiari e semantici: meglio data-action="add-to-cart" di un generico data-x="1".
  • Usa event delegation quando gli elementi possono essere creati, rimossi o aggiornati dinamicamente.
  • Controlla sempre i casi null: un selettore può non trovare nulla, quindi verifica prima di manipolare l’elemento.
  • Evita innerHTML con input non fidato: per testo semplice usa textContent.
  • Mantieni separati dati, struttura e comportamento: il DOM sarà più facile da mantenere nel tempo.

Riepilogo

La selezione e manipolazione del DOM diventa molto più solida quando usi i data-attributes come punto di riferimento. Questo approccio ti aiuta a scrivere codice meno fragile, più leggibile e più adatto a interfacce dinamiche.

Nel tutorial abbiamo visto come:

  • selezionare elementi con attributi personalizzati;
  • leggere i valori con dataset;
  • usare closest() per risalire al contesto corretto;
  • gestire eventi in modo efficiente con event delegation;
  • aggiornare il contenuto del DOM in modo controllato.

Se vuoi costruire interfacce moderne e manutenibili, questo è uno degli strumenti più utili da aggiungere al tuo kit JavaScript.

Approfondisci con risorse ufficiali

  • MDN - Using data attributes: documentazione completa sui data-attributes.
  • MDN - HTMLElement.dataset: per leggere e scrivere attributi data in JavaScript.
  • MDN - Document.querySelector(): per selezionare elementi con i selettori CSS.
  • MDN - Element.closest(): utile per risalire nella gerarchia del DOM.
  • MDN - Event delegation: concetto fondamentale per gestire eventi su elementi dinamici.

SHARE