您所拥有的称为 DOM0 处理程序 - 使用未由任何 DOM 标准定义但所有主要浏览器都支持的机制连接的处理程序。
在您的特定示例中,您可以使用 jQuery 附加您自己的 blur 处理程序,该处理程序附加一个现代或“DOM2”处理程序,它不会取代 DOM0 处理程序,因为您要做的就是添加一个 @987654324 @ 称呼。如果你想做其他任何事情,你必须做一些更复杂的事情,因为一些浏览器在调用 DOM2 处理程序之前调用 DOM0 处理程序,而其他浏览器在调用 DOM0 处理程序之前调用 DOM2 处理程序。但同样,由于您正在做的是触发一些异步操作(通过setTimeout),这并不重要,您不必关心首先调用哪个,因为您的超时代码无论如何都不会运行。
但是让我们假设你想做一些更有趣的事情:
您可以将 DOM0 处理程序替换为现代 DOM2 处理程序。您只需从 DOM 元素的反射属性中获取 DOM0 处理程序,附加您自己的处理程序,然后从您的处理程序调用 DOM0 函数。您要确保在它期望的上下文中调用 DOM0 处理程序,并使用它期望的参数。像这样的东西(这个例子使用click而不是blur,但在这两种情况下应该是一样的):
var target, dom0handler;
// Use jQuery to find the element
target = $("#target");
// Did we find it?
if (target[0]) {
// Yes, get the DOM0 handler from the DOM element itself (not the jQuery object)
dom0handler = target[0].onclick;
// Get rid of it
target[0].onclick = "";
// Hook up our own handler
target.click(function(event) {
display("Before calling DOM0 handler");
if (typeof dom0handler === "function") {
if (dom0handler.call(this, event) === false) {
event.preventDefault();
}
}
display("After calling DOM0 handler");
});
}
Live example
注意不对称性:我们读取onclick 属性并获得一个函数,但我们为它分配了一个字符串。将空白字符串分配给onclick 是最广泛兼容的清除处理程序的方法(分配null 或undefined 在某些浏览器中不起作用)。 (嗯,好吧,另一种方式是target[0].onclick = function() { },但是为什么在不需要的时候创建一个函数。)
更新:
从下面的评论中,您说您想在超时后调用 DOM0 处理程序。只需将代码包装在闭包中调用它(并处理this 问题),您就可以轻松做到这一点:
var target,
dom0handler,
activeTimeout = 0; // Use 0 for "none" because 0 is not a valid return from `setTimeout`
// Use jQuery to find the element
target = $("#target");
// Did we find it?
if (target[0]) {
// Yes, get the DOM0 handler from the DOM element itself (not the jQuery object)
dom0handler = target[0].onclick;
// Get rid of it
target[0].onclick = "";
// Hook up our own handler
target.click(function(event) {
var element = this; // Remember the element to a local, because `this` will have a different value inside the function called by `setTimeout`
// If we have a function to call and we're not busy...
if (activeTimeout === 0 && typeof dom0handler === "function") {
// ...call it
activeTimeout = setTimeout(function() {
activeTimeout = 0; // Clear this since the timeout has occurred
dom0handler.call(element, event); // Call the handler; we no longer care about its return value
}, 100);
}
return false;
});
}
并在它发生之前取消它:
if (activeTimeout !== 0) {
clearTimeout(activeTimeout);
activeTimeout = 0;
}