removeEventListener()带有不同上下文的回调

时间:2011-09-29 16:17:20

标签: javascript webkit

我正在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中所示。关于如何在使用改变函数范围的回调完成时删除事件侦听器的任何想法?

1 个答案:

答案 0 :(得分:1)

您可以使用this jsfiddle example之类的内容吗? this是触发click事件的对象。 selfA对象。

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 - second example is here。以下主要差异。

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 - general example of a one-time event handler将您的事件处理程序绑定到特定范围,调用该处理程序,并取消注册侦听器。

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);
}