Internet Explorer ed il W3C, almeno fino alla versione 9 di questo browser, hanno seguito due modelli distinti ed incompatibili per la gestione degli eventi. Da un lato il W3C propone i metodi addEventListener()
, removeEventListener()
e preventDefault()
, dall'altro IE risponde con i metodi attachEvent()
, detachEvent()
e la proprietà returnValue
. Queste sintassì gestiscono rispettivamente la creazione di un evento, la sua rimozione e l'annullamento dell'azione predefinita del browser legata ad un dato evento. In questo articolo vedremo come gestire al meglio queste differenze per giungere ad una soluzione cross-browser.
L'oggetto EventUtil
Per gestire le differenze sopra elencate, creeremo un oggetto chiamato EventUtil
che avrà tre metodi pubblici:
addEvent()
: associa un evento ad un elemento del DOMremoveEvent()
: rimuove un evento da un elemento del DOMpreventDefault()
: impedisce l'azione predefinita legata ad un dato evento
Tale oggetto si presenta così:
var EventUtil = {
//.. qui il codice
};
Vediamome i metodi in dettaglio.
addEvent()
Questo metodo accetta quattro parametri:
element
: riferimento ad un elemento del DOMeventType
: il tipo di evento, per esempioclick
omouseover
callback
: la funzione associata all'eventouseCapture
: valore booleano che serve a consentire o a prevenire la risalita dell'evento nel DOM (viene usato solo dai browser che supportano il modello W3C)
L'implementazione:
//.. qui il codice
addEvent: function(element, eventType, callback, useCapture) {
if (element.addEventListener){
element.addEventListener(eventType, callback, useCapture);
return true;
} else if (element.attachEvent) {
var r = element.attachEvent('on'+ eventType, callback);
return r;
} else {
alert('Impossibile generare evento');
}
},
// continua
Si tratta di semplici costrutti if
volti a verificare se il browser supporta il modello W3C o è Internet Explorer. Come si può notare, questo metodo usa entrambe le sintassi.
removeEvent()
Questo metodo accetta gli stessi parametri del metodo addEvent()
:
// continua
removeEvent: function(element, eventType, callback, useCapture) {
if (element.removeEventListener){
element.removeEventListener(eventType, callback, useCapture);
return true;
} else if (element.detachEvent) {
var r = element.detachEvent('on'+ eventType, callback);
return r;
} else {
alert('Impossibile rimuovere evento');
}
},
// continua
preventDefault()
Internet Explore gestisce l'oggetto event
come una proprietà dell'oggetto globale window
, mentre gli altri browser non lo fanno. Questo metodo appiana questa differenza:
// continua
preventDefault: function(event) {
event = event || window.event;
if(event.preventDefault()) {
event.preventDefault();
} else {
event.returnValue = false;
}
}
Esempio pratico
Nel seguente esempio associamo una semplice animazione ad un link:
var element = document.getElementById('test');
var button = document.getElementById('enlarge');
function expandElement() {
var widthCounter = 100;
var heightCounter = 100;
var timer = setInterval(function() {
widthCounter++;
heightCounter++;
if(widthCounter == 200 && heightCounter == 200) {
clearInterval(timer);
}
element.style.width = widthCounter + 'px';
element.style.height = heightCounter + 'px';
}, 25);
EventUtil.preventDefault();
}
EventUtil.addEvent(enlarge, 'click', expandElement, true);
Potete visionare l'esempio finale in questa pagina.