Non c'è niente di sbagliato in questa configurazione (o c'è?), Ma posso lisciarla un po '?
Guarda invece l'utilizzo della delega degli eventi. È lì che si guarda effettivamente l'evento su un contenitore che non scompare, quindi si utilizza event.target(o event.srcElementsu IE) per capire dove si è effettivamente verificato l'evento e gestirlo correttamente.
In questo modo, colleghi i gestori solo una volta e continuano a funzionare anche quando cambi il contenuto.
Ecco un esempio di delega degli eventi senza utilizzare alcuna libreria di supporto:
(function() {
var handlers = {};
if (document.body.addEventListener) {
document.body.addEventListener('click', handleBodyClick, false);
}
else if (document.body.attachEvent) {
document.body.attachEvent('onclick', handleBodyClick);
}
else {
document.body.onclick = handleBodyClick;
}
handlers.button1 = function() {
display("Button One clicked");
return false;
};
handlers.button2 = function() {
display("Button Two clicked");
return false;
};
handlers.outerDiv = function() {
display("Outer div clicked");
return false;
};
handlers.innerDiv1 = function() {
display("Inner div 1 clicked, not cancelling event");
};
handlers.innerDiv2 = function() {
display("Inner div 2 clicked, cancelling event");
return false;
};
function handleBodyClick(event) {
var target, handler;
event = event || window.event;
target = event.target || event.srcElement;
while (target && target !== this) {
if (target.id) {
handler = handlers[target.id];
if (handler) {
if (handler.call(this, event) === false) {
if (event.preventDefault) {
event.preventDefault();
}
return false;
}
}
}
else if (target.tagName === "P") {
display("You clicked the message '" + target.innerHTML + "'");
}
target = target.parentNode;
}
}
function display(msg) {
var p = document.createElement('p');
p.innerHTML = msg;
document.body.appendChild(p);
}
})();
Esempio dal vivo
Nota come se fai clic sui messaggi che vengono aggiunti dinamicamente alla pagina, il tuo clic viene registrato e gestito anche se non è presente alcun codice per agganciare gli eventi ai nuovi paragrafi aggiunti. Nota anche come i tuoi gestori sono solo voci in una mappa, e hai un gestore su document.bodyche fa tutto il dispacciamento. Ora, probabilmente lo radichi in qualcosa di più mirato di document.body, ma hai l'idea. Inoltre, in quanto sopra stiamo fondamentalmente spedendo da id, ma puoi fare corrispondenze complesse o semplici come preferisci.
Le moderne librerie JavaScript come jQuery , Prototype , YUI , Closure o molte altre dovrebbero offrire funzionalità di delega degli eventi per appianare le differenze del browser e gestire i casi limite in modo pulito. jQuery fa certamente, con entrambe le sue livee delegatefunzioni, che consentono di specificare i gestori con una gamma completa di selettori CSS3 (e poi alcuni).
Ad esempio, ecco il codice equivalente che utilizza jQuery (tranne che sono sicuro che jQuery gestisce i casi limite, la versione grezza off-the-cuff sopra non lo fa):
(function($) {
$("#button1").live('click', function() {
display("Button One clicked");
return false;
});
$("#button2").live('click', function() {
display("Button Two clicked");
return false;
});
$("#outerDiv").live('click', function() {
display("Outer div clicked");
return false;
});
$("#innerDiv1").live('click', function() {
display("Inner div 1 clicked, not cancelling event");
});
$("#innerDiv2").live('click', function() {
display("Inner div 2 clicked, cancelling event");
return false;
});
$("p").live('click', function() {
display("You clicked the message '" + this.innerHTML + "'");
});
function display(msg) {
$("<p>").html(msg).appendTo(document.body);
}
})(jQuery);
Copia dal vivo