Eventi

Introduzione
jQuery fornisce i metodi per associare i gestori di eventi (event handlers in inglese) ai selettori. Quando si verifica un evento, la funzione fornita viene eseguita. All’interno della funzione, la parola chiave $this fa riferimento all’elemento in cui si verifica l’evento.
Per maggiori dettagli sugli eventi in jQuery, è possibile consultare http://api.jquery.com/category/events/.
La funzione del gestore di eventi è in grado di ricevere un oggetto. Questo oggetto può essere utilizzato per determinare la natura del evento o, per esempio, evitare il suo comportamento predefinito.
Per maggiori informazioni sull’oggetto dell’evento, visitare http://api.jquery.com/category/events/event-object/.
Vincolare Eventi a Elementi
jQuery fornisce metodi per la maggior parte degli eventi — tra questi ci sono $.fn.click, $.fn.focus, $.fn.blur, $.fn.change, etc. Queste ultime sono le versioni ridotte del metodo $.fn.bind di jQuery. Il metodo bind è utile per vincolare (in inglese binding) la stessa funzione di gestore degli eventi a più eventi, per quando si desidera fornire le informazioni al gestore di eventi, quando si lavorando con eventi personalizzati o quando si desidera passare un oggetto a più eventi e controllori.

5.1: Collegamento di un evento utilizzando un metodo ridotto
[code lang=”javascript”] $(‘p’).click(function() {
console.log(‘click’);
});
[/code]
5.2: Collegamento di un evento utilizzando il metodo $.fn.bind
[code lang=”javascript”] $(‘p’).bind(‘click’, function() {
console.log(‘click’);
});
[/code]
5.3: Collegamento di un evento utilizzando il metodo $.fn.bind con informazione associata
[code lang=”javascript”] $(‘input’).bind(
‘click change’, // è possibile collegare più eventi
// all’elemento
{ foo : ‘bar’ }, // deve essere passato come argomento
// le informazioni associatea

function(eventObject) {
console.log(eventObject.type, eventObject.data);
// registra il tipo di evento e l’informazione
// associata { foo : ‘bar’ }
}
);
[/code]

Collegare Eventi per essere eseguiti una sola volta
A volte potrebbe essere necessario che un controller particolare venga eseguito solo una volta – e dopo di questo, abbiamo bisogno che nessun altro si esegua, o fare eseguire uno diverso. A tal fine, jQuery fornisce il metodo $.fn.one.

5.4: Cambiare controller usando il metodo $.fn.one method
[code lang=”javascript”] $(‘p’).one(‘click’, function() {
console.log(‘fatto click la prima volta!’);
$(this).click(function() { console.log(‘fatto click di nuovo!’); });
});
[/code]
Il metodo $.fn.one è utile per situazioni in cui è necessario eseguire un certo codice la prima volta che si verifica un evento su un elemento, ma non in eventi successivi.
Scollegare Eventi
Per scollegare (in inglese unbind) un gestore di eventi, è possibile utilizzare il metodo $.fn.unbind passando il tipo di evento da scollegare. Se si passa come allegato di una funzione chiamata, è possibile isolare lo scollegamento di tale funzione come secondo argomento.

5.5: Scollegare tutti i controllori di evento click in una selezione
[code lang=”javascript”] $(‘p’).unbind(‘click’);
[/code]
5.6: Scollegare un controllore di evento particolare click
[code lang=”javascript”] var foo = function() { console.log(‘foo’); };
var bar = function() { console.log(‘bar’); };

$(‘p’).bind(‘click’, foo).bind(‘click’, bar);
$(‘p’).unbind(‘click’, bar); // foo è lagato all’evento click
[/code]

Spazio di Nomi per gli Eventi
Nello sviluppo di applicazioni complesse o estensioni di jQuery, può essere utile usare i spazi di nomi (in inglese namespace) per gli eventi, e quindi prevenire che si scolleghino eventi quando no lo si desidera.
5.7: Spazio di Nomi per gli Eventi
[code lang=”javascript”] $(‘p’).bind(‘click.myNamespace’, function() { /* … */ });
$(‘p’).unbind(‘click.myNamespace’);
$(‘p’).unbind(‘.myNamespace’);
// scollega tutti gli eventi con
// lo spazio dei nomi myNamespace
[/code]
Collegamento di più eventi
Molto spesso, gli elementi in un’applicazione sono collegati ad eventi multipli, ognuno con una funzione diversa. In questi casi è possibile passare un oggetto in $.fn.bind con una o più coppie di nomi chiave/valore. Ogni nome chiave sarà il nome dell’evento, mentre ogni valore sarà la funzione da eseguire quando si verifica l’evento.
5.8: Collegare più eventi a un elemento
[code lang=”javascript”] $(‘p’).bind({
‘click’: function() {
console.log(‘fatto click!’);
},
‘mouseover’: function() {
console.log(‘il mouse è sopra!’);
}
});
[/code]
L’opzione di passare un oggetto con più eventi e funzioni a $.fn.bind è stato introdotto in jQuery 1.4.4.
L'Oggetto del Evento
Come accennato nell’introduzione, la funzione di gestore di eventi riceve un oggetto del evento, il quale contiene diversi metodi e proprietà. L’oggetto viene comunemente utilizzato per prevenire l’azione predefinita del evento attraverso il metodo preventDefault. Tuttavia, contiene anche diverse proprietà e metodi utili:

  • pageX, pageY La posizione del mouse quando l’evento si è verificato, relativa la parte superiore e sinistra della pagina.
  • type Il tipo di evento (per esempio “click”).
  • which Il pulsante o tasto premuto.
  • data Informazioni passate quando l’evento viene eseguito.
  • target L’elemento DOM che ha inizializzato l’evento.
  • preventDefault() Annulla l’azione predefinita dell’evento (per esempio: seguire un link).
  • stopPropagation() Ferma la diffusione dell’evento su altri elementi.

D’altra parte, il funzione controller ha anche accesso all’elemento DOM che ha inizializzato l’evento attraverso la parola chiave this. Per convertire l’elemento DOM in un oggetto jQuery (e potere utilizzare i metodi della libreria) deve essere scritto $(this), come illustrato di seguito:

[code lang=”javascript”] var $this = $(this);
[/code]
5.9: Annullare che facendo click su un link, questo si esegua
[code lang=”javascript”] $(‘a’).click(function(e) {
var $this = $(this);
if ($this.attr(‘href’).match(‘evil’)) {
e.preventDefault();
$this.addClass(‘evil’);
}
});
[/code]
Esecuzione automatica dei Controllori di Eventi
Attraverso il metodo $.fn.trigger, JQuery fornisce un modo per attivare i gestori di eventi su un elemento senza richiedere intervento dell’utente. Anche se questo metodo ha i suoi usi, non dovrebbe essere utilizzato per chiamare semplicemente una funzione che può essere eseguito con un clic dell’utente. Invece, si dovrebbe salvare la funzione che è necessario chiamare in una variabile e quindi passare il nome della variabile quando si effettua il collegamento (binding). In questo modo, è possibile chiamare la funzione ogni volta che si vuole invece di eseguire $.fn.trigger.
5.10: Sparare un gestore di eventi nel modo giusto
[code lang=”javascript”] var foo = function(e) {
if (e) {
console.log(e);
} else {
console.log(‘questa azione non proviene da un evento!’);
}
};

$(‘p’).click(foo);

foo(); // invece di eseguire $(‘p’).trigger(‘click’)
[/code]

Incrementare le prestazioni con la delegazione di Eventi
Quando si lavora con jQuery, spesso si aggiungono nuovi elementi alla pagina, e quando lo si fa, è necessario collegare eventi a di questi elementi — eventi che erano già collegati agli elementi nella pagina. Piuttosto che ripetere l’operazione ogni volta che si aggiunge un elemento, si può usare la delega di eventi. Con questo, è possibile associare un evento a un elemento contenitore, e poi, quando si verifica l’evento, è possibile vedere in quale elemento succede. Se tutto questo suona complicato, fortunatamente jQuery lo rende facile attraverso i metodi $.fn.live e $.fn.delegate.

La delega di eventi ha alcuni benefici, anche se non avete in programma di aggiungere altri elementi alla pagina. Il tempo necessario per legare i gestori di eventi a centinaia di elementi non è un lavoro banale; se si dispone di un grande insieme di elementi, è consigliabile utilizzare la delegazione di eventi a un elemento contenitore.

Il metodo $.fn.live è stato introdotto dalla versione 1.3 della libreria e poi, solo determinati tipi di eventi erano supportati. A partire dalla versione 1.4.2, si è introdotto $.fn.delegate che è preferito a $. Fn.live.
5.11: Delegare un evento con $.fn.delegate
[code lang=”javascript”] $(‘#myUnorderedList’).delegate(‘li’, ‘click’, function(e) {
var $myListItem = $(this);
// …
});
[/code]
5.12: Delegare un evento con $.fn.live
[code lang=”javascript”] $(‘#myUnorderedList li’).live(‘click’, function(e) {
var $myListItem = $(this);
// …
});
[/code]
Scollegare Eventi Delegati
Se è necessario rimuovere gli eventi delegati, non lo si può semplicemente scollegare. Per questo, utilizzare il $.fn.undelegate per gli eventi connessi con $.fn.delegate, e $.fn.die per gli eventi connessi con $.fn.live. Come quando si effettua un legame, opzionalmente, è possibile passare il nome di una funzione legata.
5.13: Scollegare Eventi Delegati
[code lang=”javascript”] $(‘#myUnorderedList’).undelegate(‘li’, ‘click’);
$(‘#myUnorderedList li’).die(‘click’);
[/code]
Funzioni ausiliarie degli Eventi
jQuery fornisce due funzioni ausiliarie per lavorare con gli eventi:
$.fn.hover
Il metodo $.fn.hover permette passare una o due funzioni da eseguire quando si verificano gli eventi mouseenter e mouseleave. Se si passa una sola funzione, questa sarà eseguita in entrambi gli eventi, ma invece se si passano due, la prima sarà eseguita quando si verifica l’evento mouseenter, mentre la seconda sarà eseguita quando si verifica mouseleave.

Dalla versione 1.4 di jQuery, il metodo richiede due funzioni obbligatorie.
5.14: La funzione ausiliaria hover
[code lang=”javascript”] $(‘#menu li’).hover(function() {
$(this).toggleClass(‘hover’);
});
[/code]
$.fn.toggle
Come il metodo precedente, $.fn.toggle riceve due o più funzioni, ogni volta che si verifica un evento, la funzione seguente nella lista verrà eseguita. In generale, $.fn.toggle viene utilizzata con solo due funzioni. Se si utilizzano più di due funzioni, fate attenzione, perché può essere difficile eseguire il debug del codice.
5.15: La funzione ausiliaria toggle
[code lang=”javascript”] $(‘p.expander’).toggle(
function() {
$(this).prev().addClass(‘open’);
},
function() {
$(this).prev().removeClass(‘open’);
}
);
[/code]
Esercizi
Aprire il file /exercises/index.html dal browser. Eseguire ejericio utilizzando il file /exercises/js/inputHint.js o lavorare direttamente con Firebug. Il compito è quello di utilizzare etichetta di testo dell’elemento label e applicare un “suggerimento” nella casella di immissione testo. I passi da seguire sono:

  • Impostare il valore dell’elemento input uguale al valore dell’elemento label;
  • Aggiungere la classe “hint” all’elemento input;
  • Remuover l’elemento label;
  • Collegare un evento focus nell’elemento input per rimuovere il testo di suggerimento e la classe “hint”;
  • Collegare un evento blur nel input per ripristinare il testo di suggerimento e la classe “hint” nel caso in cui un testo non hintviene inserito.

Quali altre considerazioni si dovrebbero prendere in considerazione se si desidera applicare questa funzionalità a un sito vero e proprio?

Aggiungere una navigazione a schede
Aprire il file /exercises/index.html dal browser. Eseguire ejericio utilizzando il file /exercises/js/tabs.js o lavorare direttamente con Firebug. Il compito è quello di creare una navigazione a schede per gli elementi div.module. I passi sono da seguire sono:

  • Nascondere titti gli elementi div.module;
  • Creare una lista non ordinata prima del primo div.module per utilizzarla come schede;
  • Interagire con ogni div.module usando $.fn.each. Per ciascuna, utilizzare il testo dell’elemento h2 come testo per l’elemento della lista non ordinata; Interactuar con cada div utilizando $.fn.each.
  • Collegare un evento click per ogni elemento nella lista in modo che:
    • Visualizzare il div corrispondente e nascondere l’altro;
    • Aggiungere la classe “current” al ítem selezionato;
    • Rimuovere la classe “current” su l’altro item della lista;
  • Infine, mostrare la prima scheda.