Javascript 删除子函数事件侦听器

Javascript 删除子函数事件侦听器,javascript,event-handling,listener,Javascript,Event Handling,Listener,在构建扩展的输入字段(一个复杂的日期选择器)时,我需要使用两个关键事件侦听器。一个附加到输入字段,并启动接口。这很容易 第二个附加到文档,以关闭复杂的覆盖。点击覆盖,它什么也不做。单击外部:覆盖消失,输入字段的值更新 它还需要从文档中删除事件侦听器 如果不是基于对象结构,这一切都很简单。我不是在调用独立函数。我正在调用与该字段相关联的数据对象的子函数(然后该字段将无法引用该子函数) (我还没有弄明白为什么事件附件需要嵌套在setTimeout中,但是如果我不这样做,它会立即调用自己。) 无论如何

在构建扩展的
输入
字段(一个复杂的日期选择器)时,我需要使用两个关键事件侦听器。一个附加到输入字段,并启动接口。这很容易

第二个附加到
文档
,以关闭复杂的覆盖。点击覆盖,它什么也不做。单击外部:覆盖消失,输入字段的值更新

它还需要从
文档中删除事件侦听器

如果不是基于对象结构,这一切都很简单。我不是在调用独立函数。我正在调用与该字段相关联的数据对象的子函数(然后该字段将无法引用该子函数)

(我还没有弄明白为什么事件附件需要嵌套在
setTimeout
中,但是如果我不这样做,它会立即调用自己。)

无论如何,问题是我无法成功调用
document.removeEventListener()
,因为它不是相同的初始函数

另外,我不能通过将函数作为独立函数附加来实现它,因为我需要对相关的
\uu DateField
对象的引用

如何从
文档中删除该功能


我已经看过各种线程,它们说没有办法检查通过“addEventListener”添加的事件侦听器,尽管我想知道它们是否已经过时,因为Firebug可以列出它们…

要删除它,您必须有一个对函数的引用,所以问题归结为:如何保留对函数的引用

最简单的答案是,因为您手头已经有了一个对象,如果您可以相信
在执行删除操作时是正确的,那么该对象上的属性就是:

__DateField.prototype.activate = function () {
    // …
    var t = this;
    window.setTimeout(function () {
        t.listener = function (ev) {
            t.closeDateSelector(ev)
        };
        document.addEventListener("click", listener, false);
    }, 0);
    // …
};

// To remove
__DateField.prototype.deactivate = function() {
    if (this.listener != null) {
        document.removeEventListener("click", this.listener, false);
        this.listener = null;
    }
};
或者,如果出于某种原因出现问题,可以在作用域函数中使用变量:

(function() {
    var listener = null;

    __DateField.prototype.activate = function () {
        // …
        var t = this;
        window.setTimeout(function () {
            listener = function (ev) {
                t.closeDateSelector(ev)
            };
            document.addEventListener("click", listener, false);
        }, 0);
        // …
    };

    // Later, when removing
    function removeIt() {
        if (listener != null) {
            document.removeEventListener("click", listener, false);
            listener = null;
        }
    }
})();

我怀疑这可能与从添加的事件侦听器中调用进程所嵌入的函数有关…啊,对不起,我记错了DOM events规范。它说传播路径(事件将发生的元素)必须在开始时确定,而不是更改,但它并没有说必须事先确定处理者。因此,在冒泡事件的处理程序中,将同一事件的处理程序添加到祖先元素确实会导致该处理程序被触发
setTimeout
是解决此问题的最佳方法。
(function() {
    var listener = null;

    __DateField.prototype.activate = function () {
        // …
        var t = this;
        window.setTimeout(function () {
            listener = function (ev) {
                t.closeDateSelector(ev)
            };
            document.addEventListener("click", listener, false);
        }, 0);
        // …
    };

    // Later, when removing
    function removeIt() {
        if (listener != null) {
            document.removeEventListener("click", listener, false);
            listener = null;
        }
    }
})();