bind(), live(), delegate(), on(): tutti uguali?
Una delle cose più incasinate in jQuery è capire la differenza che c’è realmente tra i vari metodi .bind(), .live(), .delegate() e .on(), poichè, di primo acchito, sembra che ognuno sia una semplice alternativa dell’altro.
Ovviamente così non è, magari qualche commento a riguardo può chiarire questi passaggi, permettendovi di decidere meglio cosa e come fare.
Per prima cosa dichiaro un po’ di codice HTML che userò per i miei esempi:
<ul id="giocatori" data-role="listview" data-filter="true"> <!-- ... altri elementi di lista ... --> <li> <a href="giocatore_dettaglio.html?id=10"> <h3>Mauro Bergamasco</h3> <p><strong>Flanker</strong></p> <p>Nazionale italiana di Rugby</p> </a> </li> <!-- ... altri elementi di lista ... --> </ul>
Il metodo bind()
$( "#giocatori li a" ).bind( "click", function( e ) {} ); $( "#giocatori li a" ).click( function( e ) {} ); $( "#giocatori li a" ).hover( function( e ) {} );
Il metodo bind() collega il tipo di evento e l’handler direttamente nell’elemento DOM in questione. E’ sicuramente il più usato, grazie alla facilità d’uso, ma qualche problema di prestazioni lo causa. Considerate che .click() non è nient’altro che un’abbreviazione di bind() stesso … ecco perchè affermo che bind() è il più usato ;).
Il problema di prestazioni è dato dal fatto che l’handler dichiarato viene applicato a tutti gli elementi del DOM coinvolti dal comando, e quello che succede è vedere reiterato lo stesso handler N volte. Questa cosa non è il massimo a livello di prestazioni.
Il metodo live()
Bastano veramente poche parole per descrivere il metodo live(). Siete soliti usarlo? Allora maggiore sarà il tempo che dovrete impiegare per sostituirlo con un metodo alternativo migliore e, sopra ogni cosa, che non sia deprecato ufficialmente da jQuery dalla 1.7. Ebbene si, notizia ferale.
La problematica principale di live() era quando lo si usava in presenza di pagine molto ricche e soprattutto quando veniva “invocato” in maniera non specifica, utilizzando un selettore generico:
$( "#giocatori li" ).live( "click", function( e ) {} );
Il metodo delegate()
$( "#giocatori" ).delegate( "li a", "click", function( e ) {} );
Live() collega l’handler dell’evento al documento generale, mentre delegate() collega le informazioni, la catena selettore/evento ( “li a”&”click” ) direttamente all’elemento nel DOM ( “#giocatori” ). Questo sistema di collegamento direttamente nel DOM element ha permesso di risolvere molte problematiche di funzionamento, rispetto che infarcire il document di una sfilza di informazioni una dietro l’altra e, cosa ancora più importante, funziona correttamente con gli elementi aggiunti dinamicamente DOPO la fine del caricamento iniziale della pagina.
Il metodo on()
Quello che, stando alle affermazioni di jQuery stessa, dovrebbe essere il vostro obiettivo futuro è proprio on(), che prenderà in un colpo solo il posto di bind(), unbind(), live(), die(), delegate() e undelegate(). Guardare per credere:
// Bind $( "#giocatori li a" ).on( "click", function( e ) {} ); $( "#giocatori li a" ).bind( "click", function( e ) {} ); // Live $( document ).on( "click", "#giocatori li a", function( e ) {} ); $( "#giocatori li a" ).live( "click", function( e ) {} ); // Delegate $( "#giocatori " ).on( "click", "li a", function( e ) {} ); $( "#giocatori " ).delegate( "li a", "click", function( e ) {} );
Come potete vedere, la potenza data a on() è notevole: a seconda di come lo chiamate in causa, lui diventa metamorfico e modifica il modo in cui l’evento è chiamato in causa.
Sicuramente l’instanziare un metodo solo, che prenda il posto di N metodi, aiuta a standardizzare il tutto, rendendolo anche più facile per jQuery da manipolare.
L’unico lato negativo, se così si può chiamare, è che, per poterlo usare, bisogna entrare un attimo nell’ottica di come cambia la gestione dell’evento a seconda di come richiamate il metodo.
Il suggerimento del maestro Zen è quello di studiare il metodo on() e cominciare ad usarlo in tutti i nuovi progetti dove userete la libreria jQuery dalla 1.7 in poi.