Javascript 使用具有不同上下文的回调removeEventListener()

Javascript 使用具有不同上下文的回调removeEventListener(),javascript,webkit,Javascript,Webkit,我正在PhoneGap中编写一个移动应用程序,但Webkit似乎存在问题,当回调上的作用域上下文发生更改时,它能够从事件列表中删除事件侦听器。以下是一个例子: Function.prototype.bind = function(scope) { var fn = this; return function () { fn.apply(scope, arguments); }; }; a = function(){}; a.prototype.tmp =

我正在PhoneGap中编写一个移动应用程序,但Webkit似乎存在问题,当回调上的作用域上下文发生更改时,它能够从事件列表中删除事件侦听器。以下是一个例子:

Function.prototype.bind = function(scope) {
    var fn = this;
    return function () {
        fn.apply(scope, arguments);
    };
};

a = function(){};
a.prototype.tmp = function(e){
    var tmp = ddd.q('#tmp');
    tmp.className = 'active';
    tmp.addEventListener('webkitAnimationEnd',this.tmp2.bind([this,tmp]),false);
}
a.prototype.tmp2 = function(e){
    this[1].removeEventListener('webkitAnimationEnd',this[0].tmp2.bind([this[0],this[1]]),false);
    this[1].className = 'inactive;
    var t2 = ddd.q('#tmp2');
    t2.className = 'active';
    t2.addEventListener('webkitAnimationEnd',this[0].setStart.bind([this,t2]),false);
};

现在,在上面的代码中,事件监听器从不剥离,每当调用回调时,事件监听器列表就会变得相当大——如Web Inspector中所示。当事件侦听器使用改变函数作用域的回调时,如何删除它们?您能使用类似的方法吗<代码>此是触发单击事件的对象
self
A
对象

Function.prototype.bind = Function.prototype.bind || function(scope) {
    var fn = this;
    return function () {
        fn.apply(scope, arguments);
    };
};

A = function() {};
A.prototype.click = function (el) {
    var self = this;
    var onClick = function () {
        el.removeEventListener('click', onClick, false);
        alert("this=" + this + "\nself=" + self + "\nel=" + el + "\nclicked");
    }
    el.addEventListener('click', onClick, false);
}
A.prototype.toString = function () {
    return "I am an A!";
}

a = new A();
a.click(document.getElementById("a1"));
a.click(document.getElementById("a2"));
更新1-。主要区别如下

function createOnClickHandler (scope, outerThis, el) {
    var onClick = (function (evt) {
        el.removeEventListener('click', onClick, false);
        alert("this=" + this + "\nouterThis=" + outerThis + ", \nel=" + el + "\nclicked");
    }).bind(scope);
    return onClick;
}

A = function() {};
A.prototype.click = function (el) {
    var ob = {
        toString: function () {
            return "I am an ob!";
        }
    };
    el.addEventListener('click', createOnClickHandler(ob, this, el), false);
}
更新2-将事件处理程序绑定到特定范围,调用该处理程序,并注销侦听器

function createOneTimeHandler (evtName, fn, scope, el) {
    var bound = fn.bind(scope);
    var onEvent = function (evt) {
        el.removeEventListener(evtName, onEvent, false);
        bound(evt);
    };
    el.addEventListener(evtName, onEvent, false);
}

您是否正确使用了
bind
?它应该是
.bind(this,arg1,arg2,…)
这样你就可以避免将
this
作为一个数组了?这并不一定能解决这个问题。问题是我必须改变范围,而且经常是不在对象上下文中的内容。这是一个非常好的想法,但在这种情况下不适用。我会玩弄它,看看它是怎么飞的;不过,我仍然需要一个更通用的用例来删除我更改范围的事件侦听器。好的,我想我明白你的意思了,所以我添加了第二个绑定到全新对象的示例。