Aggiungere un listener è veramente semplice con la sintassi del w3c:
document.addEventListener("click", function() { alert(!!this.getElementById) }, 0);
in teoria l’uso della sintassi alternativa di IE, attachEvent, dovrebbe avere la stessa semplicità:
document.attachEvent("click", function() { alert(!!this.getElementById) });
Peccato che attachEvent soffra di diversi bug; il primo si evince eseguendo l’esempio qui sopra: l’alert restitisce false; come è possibile?
Ciò dipende dal fatto che lo scope nella funzione eseguita non sarà l’oggetto stesso, bensì la finestra ( window insomma ).
Ma non è finita quì: un altro bug di cui soffre attachEvent è l’ordine in cui i listener sono eseguiti; se ad esempio proviamo ad attaccare questi listener:
window.attachEvent("load", function() { alert("primo listener") });
window.attachEvent("load", function() { alert("secondo listener") });
window.attachEvent("load", function() { alert("terzo listener") });
window.attachEvent("load", function() { alert("quarto listener") });
verranno eseguiti in quest’ordine:
terzo listener
quarto listener
primo listener
secondo listener
Tutto ciò non ha alcun senso, se non la nostra disperazione
. Che fare allora? L’unica soluzione è crearci una funzione che richiami attachEvent evitandone i bug; di certo non possiamo sovrascrivere il metodo visto che IE non supporta il costruttore HTMLElement. $addListener = function(obj, ev, lis) {
if(obj.addEventListener)
obj.addEventListener(ev, lis, 0);
else if(obj.attachEvent) {
if(!obj.events) obj.events = {}
if(!obj.events[ev]) {
obj.events[ev] = [];
obj.attachEvent("on"+ev, function() {
for(var i = 0, l = obj.events[ev].length; i!=l; i++) {
obj.events[ev][i]();
}
});
}
var fn = function() { lis.call(obj) };
obj.events[ev].push(fn);
}
}
Non ho avuto il tempo di testarla ma dovrebbe funzionare.
EDIT: Ho modificato la funzione, prima non andava…