开发者

removeEventListener() with a callback with a different context

I'm writing a mobile app in PhoneGap, but there seems to be an issue with Webkit and its ability to remove event listeners from its event list when there's a scope context change on the callback. Below is an example:

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

Now, in the above code, the event listeners never peel off, and whenever the callback gets invoked, the event listener list becomes rather large -- as demonstrated in Web Inspector. Any ideas on how to remove event listeners when they're done using callbacks that change function scope?


Can you use something like this jsfiddle example? this is the object on which the click event is fired. self is the A object.

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

Update 1 - second example is here. Major differences below.

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

Update 2 - general example of a one-time event handler that binds your event handler to a particular scope, calls that handler, and unregisters the listener.

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜