В этой настройке нет ничего плохого (или есть?), Но можно ли немного сгладить?
Вместо этого посмотрите на использование делегирования событий. Вот где вы на самом деле наблюдаете за событием в контейнере, который не исчезает, а затем используете event.target
(или event.srcElement
в IE), чтобы выяснить, где на самом деле произошло событие, и правильно его обработать.
Таким образом, вы прикрепляете обработчик (-ы) только один раз, и они продолжают работать, даже когда вы меняете контент.
Вот пример делегирования событий без использования вспомогательных библиотек:
(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);
}
})();
Живой пример
Обратите внимание, как если вы щелкаете сообщения, которые динамически добавляются на страницу, ваш щелчок регистрируется и обрабатывается, даже если нет кода для привязки событий к добавляемым новым абзацам. Также обратите внимание, что ваши обработчики - это просто записи на карте, и у вас есть один обработчик, document.body
который выполняет всю отправку. Теперь вы, вероятно, укорените это в чем-то более целенаправленном document.body
, но вы поняли идею. Кроме того, в приведенном выше примере мы в основном осуществляем рассылку id
, но вы можете выполнить сопоставление настолько сложным или простым, насколько захотите.
Современные библиотеки JavaScript, такие как jQuery , Prototype , YUI , Closure или любые другие, должны предлагать функции делегирования событий, чтобы сгладить различия браузеров и аккуратно обрабатывать крайние случаи. JQuery , конечно же, с обеих его live
и delegate
функций, которые позволяют Вам определять обработчики , используя полный спектр CSS3 селекторов (и затем некоторые).
Например, вот эквивалентный код с использованием jQuery (за исключением того, что я уверен, что jQuery обрабатывает крайние случаи, а необработанная исходная версия выше не работает):
(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);
Живая копия