我已经定义了onclick事件。我想添加额外的回调函数,在已定义的回调函数之前调用。
- 如何将事件添加到特定事件类型队列的开头?
我已经定义了onclick事件。我想添加额外的回调函数,在已定义的回调函数之前调用。
如果您在IE中使用attachEvent
,则无法保证事件触发的顺序。请参见http://msdn.microsoft.com/en-us/library/ms536343(VS.85).aspx
如果您在同一对象上的同一事件上附加多个函数,则这些函数将在对象的事件处理程序调用后立即以随机顺序调用。
(实际上,我看到事件是按相反的顺序调用的,而不是随机的)。 无论如何,库通常倾向于深入使用attachEvent
,因此您将面临相同的问题。
话虽如此,如果您可以检查节点的“click”处理程序(例如,在标记中设置了“onclick”属性),那么您可以将“您的”放在“他们的”之前:
var nodes = document.getElementsByTagName('*'); // collect your nodes however
for(var i=0; i < nodes.length; i++) {
var node = nodes[i];
if(!node.onclick)
continue;
// At this point we have a node with an "onclick" attr.
// Hijack onclick to do something else first.
var original = node.onclick;
node.onclick = function() {
doSomethingElse();
return original.apply(this, arguments);
}
}
请参考此答案,了解如何检查其他库中节点的事件(如果您正在使用其他库)。您可能还可以使用它来doSomethingElse()
与这些库一起使用。
太棒了。这让我查阅了jQuery文档,我发现将crescentfresh的解决方案与jQuery的unbind()方法(类似于Extjs.removeAll())结合起来可以解决我的问题。
因此,最终我有了以下代码:
this.onclick = function( e )
if ( /*trigger clause*/ true ) {
//cancel all events
$(this).unbind();
return false;
} else {
//continue processing
return original ? original.apply(this, arguments) : true;
}
}
谢谢你们的建议!
PS 这些混蛋制造了这个糟糕的回复编辑器吗?!在这里粘贴一些代码真是让人头痛。
PPS 不幸的是,由于声望不足,我不能为两个答复投票,也不能为您的答复提高有用的标记,也不能标记多个答案为可接受。所以,请原谅我。这个愚蠢的论坛引擎,但这里真的很酷。
addEventListener 允许您添加另一个事件。请注意,在IE中,您将不得不使用attachEvent。
这不会让您定义事件的顺序 - 显然您无法预测事件触发的顺序。因此,如果您真的想要一个可预测的事件队列,您将不得不自己实现它。
您可以使用preventDefault()停止事件的默认操作,或使用stopPropagation()停止嵌套事件的传播,以仅触发您特定的事件。
但是,原生地暂停或延迟事件而不使用setTimeout(),停止、保存其状态并稍后重新排队是不可能的。
您是否正在使用jQuery框架?我目前正在使用ExtJS并找到了一个您可以使用或复制的类。
让我们看看 http://extjs.com/deploy/dev/docs/ Ext > EventManager > removeAll()
removeAll( String/HTMLElement el ) : void 从元素中删除所有事件处理程序。通常,您将直接在Element上使用Ext.Element.removeAllListeners而不是调用此版本。参数:el: String / HTMLElement要从中删除事件的id或html元素 Returns: void
我认为您可以将标记body
设置为HTMLElement以关闭所有事件。(抱歉没有进行测试)
在此处下载http://extjs.com/products/extjs/build/>如果您正在使用jquery,则选择jquery适配器> extcore就足够了(它包含EventManager.js)。
另一方面,就像crescentfresh(答案#4)一样,我编写了此示例代码以应用于所有节点事件:
var nodes = document.getElementsByTagName('*'); // collect your nodes however
for(var i=0; i < nodes.length; i++) {
var node = nodes[i];
Ext.EventManager.removeAll(node);
}
}
如果您在使用ExtJS时遇到问题,请告诉我,我可以提供帮助。如果我的回答对您有用,请为我投票。
您可以通过加载正确参数的示例函数来简单地停止事件监听器:
function removeEvent(obj,type,fn){
if(obj.removeEventListener) obj.removeEventListener(type,fn,false);
else if(obj.detachEvent){
obj.detachEvent("on"+type,obj[type+fn]);
obj[type+fn]=null;
obj["e"+type+fn]=null;
}
}
此外,您可以在杀死其他侦听器的事件中触发一个setTimeout,并通过外部或另一个setTimeout逐个重新启用侦听器。
一个调试事件的库,可能会很有用。