stopImmediatePropagation

stopImmediatePropagation

我正在为Javascript库处理事件处理代码,并且正在尝试实现类似于stopImmediatePropagation()的功能,该功能也可以在IE 6中使用。

事件处理当前工作的方式是,我们的事件处理代码向对象注册,然后用户向我们的事件处理程序注册所有事件。

我尝试模拟stopImmediatePropagation()的第一种方法是简单地将该方法添加到事件中(如果尚不存在):

if (event != null && event.isImmediatePropagationEnabled == null) {
    event.stopImmediatePropagation = function () {
        this.isImmediatePropagationEnabled = false;
    };
    event.isImmediatePropagationEnabled = true;
    event.isImmediatePropagationStopped = function () {
        return !this.isImmediatePropagationEnabled;
    };
}

调用用户的事件处理程序回调时,它们将在我们获得的同一事件对象中传递。如果愿意,他们可以在事件上调用stopImmediatePropagation()。

当我们遍历向我们注册的所有事件处理回调时,我们每次都会检查传播 bool 值:
given some event
for [all the callbacks] {
    if (event != null &&
        event.isImmediatePropagationStopped != null &&
        event.isImmediatePropagationStopped()) {
        stopPropagation = true;
        break;
    }

    execute the callback, passing in the event
}

这在某些浏览器中效果很好。因为事件仍然存在,所以即使退出我们的事件处理代码并且事件冒泡到下一个元素,一旦再次击中我们的事件处理代码,isImmediatePropagationStopped属性仍然存在,因此不再执行(向我们注册的)回调。

在Internet Explorer中(即使在8中),这也不起作用。出于同样的考虑,一切都很好。但是一旦事件冒泡,似乎就生成了一个全新的事件对象,并且我们失去了isImmediatePropagationStopped属性。这意味着我们无法检查用户是否关闭了传播。

所以我的问题是,有人对如何执行此操作有任何想法吗?我知道jquery管理类似的专长(http://bugs.jquery.com/ticket/3355),但它们的执行方式类似-将其存储在对象的额外数据中。我不知道的是,对象的非持久性不会像我一样伤害他们。 (并且由于各种原因,在这里不可以使用jquery本身)

如果有人有任何见解-或者是因为比我更了解Javascript,或者是因为他们可以想到一种巧妙的方式来做到这一点-我将不胜感激。谢谢!

最佳答案

尝试稍微改变一下功能:

event.stopImmediatePropagation = function () {
    this.isImmediatePropagationEnabled = false;
    this.cancelBubble = true;
};

该“cancelBubble”标志是IE的事情,它应防止事件使父DOM元素链冒泡。

09-25 19:36