将事件添加到队列头部

3

我已经定义了onclick事件。我想添加额外的回调函数,在已定义的回调函数之前调用。

  • 如何将事件添加到特定事件类型队列的开头?
6个回答

1

如果您在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()与这些库一起使用。


1

太棒了。这让我查阅了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 不幸的是,由于声望不足,我不能为两个答复投票,也不能为您的答复提高有用的标记,也不能标记多个答案为可接受。所以,请原谅我。这个愚蠢的论坛引擎,但这里真的很酷。


0

addEventListener 允许您添加另一个事件。请注意,在IE中,您将不得不使用attachEvent。

这不会让您定义事件的顺序 - 显然您无法预测事件触发的顺序。因此,如果您真的想要一个可预测的事件队列,您将不得不自己实现它。


0

0

您是否正在使用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时遇到问题,请告诉我,我可以提供帮助。如果我的回答对您有用,请为我投票。


-2

您可以通过加载正确参数的示例函数来简单地停止事件监听器:

   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逐个重新启用侦听器。

一个调试事件的库,可能会很有用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接