JavaScript,停止其他事件侦听器

时间:2009-07-12 00:16:22

标签: javascript events

想象一下,我有这段代码:

var myFunc1 = function(event) {
    alert(1);
}
var myFunc2 = function(event) {
    alert(2);
}

element.addEventListener('click', myFunc1);
element.addEventListener('click', myFunc2);

当click事件被触发时,调用myFunc1,然后调用myFunc2。但是,如果满足myFunc1中的某些条件,我如何(如果可能的话)停止调用myFunc2? event.stopPropagation()不是解决方案,因为这不是事件捕获/冒泡问题。

感谢。

5 个答案:

答案 0 :(得分:8)

DOM Level 3方法event.stopImmediatePropagation正是我在这里所需要的。 不幸的是,它目前没有在任何浏览器中实现(我知道)

答案 1 :(得分:6)

还有一个问题:执行事件侦听器的顺序是未定义的。你需要自己处理事件调度来解决这个问题,这导致我们对llimllib建议的一些变体。

function dispatchSleightEvent(evt) {
    var listeners = evt.currentTarget.sleightListeners[evt.type];
    // can't use for-in because enumeration order is implementation dependent
    for (var i=0; i<listeners.length; ++i) {
       if (listeners[i]) {
         if (! listeners[i].call(evt.currentTarget, evt)) {
           return false;
         }
       }
    }
    return true;
}

function mixinSleightTarget(obj) {
  if (! obj.sleightListeners) {
    obj.sleightListeners = {}
    obj.addSleightListener = function(type, listener) {
        if (!this.sleightListeners[type]) {
            this.sleightListeners[type] = [];
            this.addEventListener(type, dispatchSleightEvent);
        }
        if (!this.sleightListeners[type+listener] {
          this.sleightListeners[type+listener] = this.sleightListeners[type].length;
          this.sleightListeners[type].push(listener);
        }
    }
    obj.removeSleightListener = function(type, listener) {
        if (this.sleightListeners[type+listener] {
          delete this.sleightListeners[type][this.sleightListeners[type+listener]];
          delete this.sleightListeners[type+listener];
        }          
    }
  }
}

此代码完全未经测试。要在单个目标上停止事件调度,事件侦听器将返回false。如果你想要更多的数据隐藏,你可以从功能编程的角度重写上述内容,尽管这可能会引入内存泄漏。

答案 2 :(得分:4)

仍在寻找更好的解决方案,但这可能是唯一的方法:

var myFunc1 = function(event) {
    alert(1);
    if (something) {
        event.cancel = true;
    }
}
var myFunc2 = function(event) {
    if (event.cancel) {
        return;
    }
    alert(2);
}

document.body.addEventListener('click', myFunc1, false);
document.body.addEventListener('click', myFunc2, false);

欢迎思考/评论。

答案 3 :(得分:2)

我将从满足您迄今为止给出的约束的最简单答案开始。如果它不符合您尚未指定的某些条件,请告诉我,我会更新它。

只允许一个点击处理程序,并根据那里的条件调用函数。您的测试代码变为:

var myFunc1 = function(event) {
    alert(1);
}
var myFunc2 = function(event) {
    alert(2);
}
var clickHandler = function(event) {
    if (f1active) myFunc1(event);
    if (f2active) myFunc2(event);
}

element.addEventListener('click', clickHandler);
var f1active = true;
var f2active = true;

您当然可以在clickHandler中添加您想要的任何条件。

答案 4 :(得分:0)

我是第二个outis解决方案,听起来你需要使用自己的事件调度程序来装饰或调整现有的DOM事件调度模型。

根据2007年的动作脚本调度程序实施,进行了一些搜索并找到了这个可能符合您需求的链接。

http://positionabsolute.net/blog/2007/06/event-dispatcher.php

当然,我不是一个javascripter,所以如果这不相关,请告诉我。