removeEventListener () с обратным вызовом с другим контекстом - PullRequest
0 голосов
/ 29 сентября 2011

Я пишу мобильное приложение в 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 Ответ

1 голос
/ 29 сентября 2011

Можете ли вы использовать что-то вроде в этом примере jsfiddle ?this - объект, для которого происходит событие щелчка.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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...