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 esempioclickomouseovercallback: 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.