jQuery .each(): Guida Completa all'Iterazione di Elementi e Oggetti

Scopri come utilizzare il metodo .each() di jQuery per scorrere liste di elementi DOM e oggetti JavaScript in modo efficiente e pulito.

Introduzione al metodo .each() di jQuery

Nel mondo dello sviluppo web, una delle operazioni più comuni è l'iterazione. Che si tratti di modificare il colore di tutti i paragrafi di una pagina, di sommare i valori di una tabella di prezzi o di validare tutti i campi di un modulo, abbiamo costantemente bisogno di "scorrere" un insieme di elementi per applicare la stessa logica a ognuno di essi.

Sebbene JavaScript moderno offra metodi come forEach() o i cicli for...of, jQuery ha introdotto il metodo .each() per semplificare drasticamente questo processo. La potenza di .each() risiede nella sua capacità di integrarsi perfettamente con il sistema di selezione di jQuery, permettendoci di passare da un selettore (che restituisce un oggetto jQuery) all'esecuzione di un'azione su ogni singolo elemento DOM contenuto in quell'oggetto.

In questa lezione, esploreremo a fondo come funziona .each(), la differenza tra l'iterazione di elementi DOM e quella di oggetti/array semplici, e vedremo i casi d'uso più comuni per rendere il tuo codice più leggibile e manutenibile.

Come funziona .each() per gli elementi DOM

Quando utilizziamo un selettore jQuery, come $('p') o $('.mio-elemento'), non otteniamo un singolo elemento, ma un "oggetto jQuery" che agisce come un wrapper attorno a un array di elementi DOM. Mentre molti metodi di jQuery (come .css() o .hide()) sono già "impliciti" (ovvero vengono applicati automaticamente a tutti gli elementi della selezione), ci sono situazioni in cui abbiamo bisogno di un controllo granulare su ogni singolo elemento.

Il metodo .each() accetta una funzione di callback che viene eseguita una volta per ogni elemento del set. Questa funzione riceve due parametri fondamentali:

  1. L'indice (index): La posizione dell'elemento corrente all'interno del set (parte da 0).
  2. L'elemento (element): Il riferimento all'elemento DOM nativo di JavaScript.

Sintassi di base

Ecco la struttura tipica di un ciclo .each() applicato a elementi HTML:

$('selettore').each(function(index, element) {
    // Codice da eseguire per ogni elemento
    console.log('Elemento numero ' + index + ' è: ' + element);
});

È importante notare che all'interno della funzione di callback, la parola chiave this si riferisce all'elemento DOM corrente. Quindi, $(this) è il modo più rapido per trasformare l'elemento DOM nativo in un oggetto jQuery e poter utilizzare nuovamente tutti i metodi della libreria.

Esempi Pratici di Implementazione

Per comprendere davvero l'utilità di .each(), analizziamo tre scenari reali che ogni sviluppatore web incontra frequentemente.

Scenario 1: Manipolazione dinamica di una lista

Immaginiamo di avere una lista di prodotti e di voler aggiungere una classe CSS differente a seconda che la posizione dell'elemento sia pari o dispari (effetto zebra manuale) o di voler formattare il testo basandoci su un attributo.

<ul id='lista-prodotti'>
    <li data-prezzo='10'>Prodotto A</li>
    <li data-prezzo='20'>Prodotto B</li>
    <li data-prezzo='30'>Prodotto C</li>
</ul>
$('#lista-prodotti li').each(function(index) {
    // Recuperiamo il prezzo dall'attributo data
    let prezzo = $(this).data('prezzo');
    
    // Se il prezzo è maggiore di 15, aggiungiamo una classe 'costoso'
    if (prezzo > 15) {
        $(this).addClass('costoso');
    }
    
    console.log('Controllato prodotto ' + (index + 1) + ' con prezzo ' + prezzo);
});

In questo esempio, .each() ci permette di leggere un dato specifico di ogni elemento e prendere una decisione logica individuale, cosa che un semplice .addClass() globale non potrebbe fare.

Scenario 2: Somma di valori numerici da input

Un caso d'uso classico è il calcolo del totale di un carrello o di un modulo di preventivo.

<div class='prezzo-item'>10.00</div>
<div class='prezzo-item'>25.50</div>
<div class='prezzo-item'>5.00</div>
<div id='totale'>Totale: 0</div>
let sommaTotale = 0;

$('.prezzo-item').each(function() {
    // Estraiamo il testo, rimuoviamo eventuali spazi e convertiamo in numero
    let valore = parseFloat($(this).text());
    if (!isNaN(valore)) {
        sommaTotale += valore;
    }
});

$('#totale').text('Totale: ' + sommaTotale.toFixed(2));

Qui, .each() è essenziale perché dobbiamo accumulare un valore in una variabile esterna al ciclo.

Scenario 3: Gestione di attributi e link

Supponiamo di voler scansionare tutti i link di una pagina e aggiungere un'icona "esterno" a tutti i link che portano a un dominio diverso dal nostro.

$('a').each(function() {
    let href = $(this).attr('href');
    if (href && href.indexOf('http') === 0 && href.indexOf(window.location.hostname) === -1) {
        $(this).append(' <img src="external-icon.png" />');
    }
});

jQuery.each() vs .each(): La differenza fondamentale

Uno degli errori più comuni per i principianti è confondere il metodo .each() (quello che abbiamo visto finora) con la funzione utility $.each(). Sebbene sembrino identici, hanno scopi leggermente diversi.

Il metodo .each() (Instance Method)

Questo metodo viene chiamato su un oggetto jQuery esistente. È progettato specificamente per iterare gli elementi del DOM selezionati.

La funzione $.each() (Static Utility Method)

$.each() è una funzione generica di jQuery che può iterare non solo elementi DOM, ma qualsiasi oggetto JavaScript o array. La sintassi è invertita: l'oggetto da iterare è il primo parametro della funzione.

// Esempio di iterazione di un array semplice con $.each()
const colori = ['Rosso', 'Verde', 'Blu'];

$.each(colori, function(index, valore) {
    console.log('Colore ' + index + ': ' + valore);
});

Perché usare $.each() invece del ciclo for classico? Perché $.each() è più conciso e garantisce la compatibilità cross-browser, gestendo internamente alcune peculiarità degli oggetti JavaScript che potrebbero causare errori in versioni molto vecchie di browser se usati con cicli for...in senza controlli di sicurezza.

Errori Comuni e Soluzioni

1. Dimenticare $(this)

Il problema più frequente è cercare di usare metodi jQuery direttamente su this.

Errore: this.addClass('active'); $
ightarrow$ this è un elemento DOM nativo, e .addClass() non esiste nel DOM nativo. Soluzione: $(this).addClass('active'); $
ightarrow$ Avvolgiamo l'elemento in un oggetto jQuery.

2. Confondere l'ordine dei parametri

In .each() per elementi DOM, l'ordine è (index, element). In $.each() per array, l'ordine è lo stesso (index, value). Tuttavia, in altri contesti di JavaScript (come Array.prototype.forEach), l'elemento viene prima dell'indice. È fondamentale controllare sempre la documentazione.

3. L'uso di 'return' all'interno di .each()

In un ciclo for tradizionale, break interrompe il ciclo e continue passa all'elemento successivo. In .each(), le parole chiave break e continue non funzionano.

  • Per simulare un continue: usa return true; (la funzione termina l'esecuzione per l'elemento corrente e passa al prossimo).
  • Per simulare un break: usa return false; (il ciclo si interrompe completamente).

FAQ rapide

Q: È più veloce .each() o un ciclo for classico?

*A: Il ciclo for nativo di JavaScript è tecnicamente più veloce in termini di performance pure. Tuttavia, per la maggior parte delle applicazioni web, la differenza è impercettibile e la leggibilità e facilità di scrittura di .each() prevalgono sulla velocità millimetrica.

Q: Posso usare le arrow functions (=>) con .each()?

*A: Sì, puoi, ma attenzione! Le arrow functions non hanno il proprio this. Se usi () => { ... }, $(this) non si riferirà più all'elemento DOM corrente, ma al contesto globale. Se usi le arrow functions, devi obbligatoriamente usare il secondo parametro della callback: $('.elem').each((index, element) => { $(element).hide(); });.

Prossimi Passi

Ora che hai padronggiato l'iterazione con .each(), sei pronto per esplorare concetti più avanzati di manipolazione del DOM. Ti consigliamo di approfondire i seguenti argomenti:

  1. Il filtraggio con .filter() e .not(): Invece di iterare tutti gli elementi e usare degli if all'interno di .each(), a volte è più efficiente filtrare la selezione prima di iniziare il ciclo.
  2. La gestione degli eventi delegati: Impara come gestire eventi su elementi che vengono aggiunti dinamicamente alla pagina dopo che il ciclo .each() è stato eseguito.
  3. JavaScript ES6+: Prova a confrontare .each() con Array.from($('.elementi')).forEach(...) per capire come jQuery si interfaccia con gli standard moderni del linguaggio.

L'iterazione è la base di ogni interazione complessa. Pratica creando piccole utility: un calcolatore di sconti, un sistema di evidenziazione parole chiave o un validatore di moduli personalizzato. Buon coding!