No hay nada de malo en esta configuración (¿o no?), Pero ¿puedo suavizarlo un poco?
En su lugar, considere usar la delegación de eventos. Ahí es donde realmente observa el evento en un contenedor que no desaparece, y luego usa event.target(o event.srcElementen IE) para averiguar dónde ocurrió realmente el evento y manejarlo correctamente.
De esa manera, solo adjunta los controladores una vez y seguirán funcionando incluso cuando intercambie contenido.
A continuación, se muestra un ejemplo de delegación de eventos sin utilizar ninguna biblioteca auxiliar:
(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);
}
})();
Ejemplo vivo
Tenga en cuenta que si hace clic en los mensajes que se agregan dinámicamente a la página, su clic se registra y se maneja a pesar de que no hay código para enganchar eventos en los nuevos párrafos que se agregan. También tenga en cuenta que sus controladores son solo entradas en un mapa, y tiene un controlador en el document.bodyque realiza todo el envío. Ahora, probablemente arraigue esto en algo más específico que document.body, pero ya entiende la idea. Además, en lo anterior básicamente estamos enviando por id, pero puede hacer una coincidencia tan compleja o simple como desee.
Las bibliotecas de JavaScript modernas como jQuery , Prototype , YUI , Closure o cualquiera de varias otras deberían ofrecer funciones de delegación de eventos para suavizar las diferencias del navegador y manejar los casos extremos de manera limpia. jQuery ciertamente lo hace, con sus funciones livey delegate, que le permiten especificar controladores usando una gama completa de selectores CSS3 (y más).
Por ejemplo, aquí está el código equivalente usando jQuery (excepto que estoy seguro de que jQuery maneja casos extremos que la versión sin procesar de arriba no lo hace):
(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 en vivo