如何在事件发生之前删除监听器?

Posted

技术标签:

【中文标题】如何在事件发生之前删除监听器?【英文标题】:How to remove a listener before an event takes place? 【发布时间】:2013-08-08 08:51:40 【问题描述】:

我的问题与此类似:How to prevent itemclick event on check change in Ext Js Tree。

但是,它没有为我的问题提供解决方案。所以,我的问题是:问题是我的树中有三个侦听器,在checkchange 上,我想阻止itemclick 事件。但一切都以意想不到的顺序执行。代码是:

checkchange:function(node,check)                           
  alert("1");
,
itemclick:function(view,rec,item,index,eventObj)
  alert("2");
,
render:function()
  Ext.getCmp('mytree').on('checkchange',function(node,check)
    alert("0");
    Ext.getCmp('mytree').removeListener('itemclick',this);
  );

当我检查树中的一个节点时,我首先看到alert(2),然后是alert(1),然后才看到alert(0)。所以,应该删除监听器的代码发生在最后,我想要相反的。

编辑:

我不想完全删除itemclick 事件。更合适的词是“停止”一个事件,防止它发生。

编辑:

解决方案是在 itemclick 事件中进行 e.getTarget() 检查。所以,我在itemclick 事件中的代码现在看起来像这样:

itemclick:function(view, record, item, index, e, eOpts)
  if(e.getTarget('span',1,true))
     // all other code which should take place in case
     // itemclick event does not come from checkbox element
  

【问题讨论】:

【参考方案1】:

首先,了解触发事件的顺序很重要:

    render itemclick checkchange

其次,了解您为 render 事件定义的函数中发生了什么很重要。

代码所做的是向您已经为 checkchange 函数定义的代码添加额外的代码,因此 checkchange 在运行时会提醒 1 然后是 0(您所看到的)。此外,它将删除itemclick 侦听器。这意味着您第二次单击某个节点时,它的行为应该有所不同。

如果您想在渲染时立即抑制 itemclick 事件,您应该取消嵌套 removeListener 调用,因此:

render:function()
  this.removeListener('itemclick',this).on('checkchange',function(node,check)
    alert("0");    
  );

或者,您可以简单地删除 itemclick 事件侦听器本身。

如果您想更改处理itemclick 事件的方式,您还可以使用以下方法之一拦截事件本身:

itemclick:function(view,rec,item,index,eventObj)
  eventObj.preventDefault(); //or
  eventObj.stopPropagation(); //or
  eventObj.stop();
,

不过,尚不清楚您要完成什么。

【讨论】:

你说的绝对有道理。但是,我测试了我的代码,发现在第一次检查事件之后,警报的顺序保持不变。所以,这个“这意味着你第二次点击一个节点时它应该表现不同”结果是不正确的。此外,我测试了您的代码(最适合我的第一部分)并收到错误 this.removeListener is undefined。在我看来,你和我都试图以不恰当的方式使用这种方法。顺便说一句,我使用的是 Ext 4.1。 尝试将 this.removeListener('itemclick',this) 更改为 this.removeListener('itemclick') - 顺便注意文档声明它仅适用于使用 addListener 添加的事件。看来您真正想要的不是删除 itemclick 事件,而是停止传播或什么都没有发生? 我简化了我的代码。我不想完全删除 itemclick 事件,因为它里面有更多的代码。 我更改为 this.removeListener('itemclick') 但仍然遇到同样的错误。而且,顺便说一句,我没有通过 addListener 添加监听器。那么,在这种情况下是否可以删除其中一个侦听器? 在这种情况下您应该更改您的问题,因为您声明警报 2 发生在 1 之前,表明 itemclick 在 checkchange 之前。请完全具体说明您的目标,因为回读时存在一些相互矛盾的信息,因此很难提供进一步的帮助我害怕

以上是关于如何在事件发生之前删除监听器?的主要内容,如果未能解决你的问题,请参考以下文章

如何删除 addClsOnOver 监听器 ExtJS

ContentObserver监听媒体库变化

监听器

如何监听div内容的改变?

JavaScript Promise小结

如何删除某些元素的所有事件侦听器而不使用其子元素