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

发布于 2024-12-07 03:20:46 字数 864 浏览 0 评论 0原文

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦回梦里 2024-12-14 03:20:46

你能使用像这个jsfiddle示例这样的东西吗? this 是触发点击事件的对象。 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 - 第二个示例在这里。主要差异如下。

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

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文