这个设置没有任何问题(或者有没有问题?),但我可以稍微平滑一下吗?
看看使用事件委托。这就是您实际在不会消失的容器上观察事件的地方,然后使用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);
实时复制