Tidak ada yang salah dengan pengaturan ini (atau apakah ada?), Tetapi bisakah saya menghaluskannya sedikit?
Lihat menggunakan delegasi acara sebagai gantinya. Di situlah Anda benar-benar menonton acara di wadah yang tidak hilang, dan kemudian menggunakan event.target(atau event.srcElementdi IE) untuk mencari tahu di mana peristiwa sebenarnya terjadi dan menanganinya dengan benar.
Dengan begitu, Anda hanya memasang penangan satu kali, dan penangan tetap berfungsi bahkan saat Anda menukar konten.
Berikut adalah contoh delegasi acara tanpa menggunakan lib helper:
(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);
}
})();
Contoh langsung
Perhatikan bagaimana jika Anda mengklik pesan yang secara dinamis ditambahkan ke halaman, klik Anda didaftarkan dan ditangani meskipun tidak ada kode untuk menghubungkan peristiwa pada paragraf baru yang ditambahkan. Perhatikan juga bagaimana penangan Anda hanyalah entri di peta, dan Anda memiliki satu penangan di atasnya document.bodyyang melakukan semua pengiriman. Sekarang, Anda mungkin mengakar ini pada sesuatu yang lebih bertarget daripada document.body, tetapi Anda mengerti. Selain itu, di atas pada dasarnya kami mengirim id, tetapi Anda dapat melakukan pencocokan sesulit atau sesederhana yang Anda suka.
Library JavaScript modern seperti jQuery , Prototype , YUI , Closure , atau beberapa lainnya harus menawarkan fitur delegasi acara untuk memperhalus perbedaan browser dan menangani kasus edge dengan rapi. jQuery tentu melakukannya, dengan its livedandelegate fungsinya, yang memungkinkan Anda menentukan penangan menggunakan berbagai selektor CSS3 (dan kemudian beberapa).
Misalnya, inilah kode yang setara menggunakan jQuery (kecuali saya yakin jQuery menangani kasus tepi versi mentah off-the-cuff di atas tidak):
(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);
Salinan langsung