Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
314 views
in Technique[技术] by (71.8m points)

javascript - Why does removeeventlistener not work in this object context?

I am working on a game and I would like to abstract my UI, and bind unbind events based on various game states. But I can't figure out why this event is not being removed. It seems the scope is correct in the handler.

fiddle

relevant (stripped down) js:

var controls = {
    game : {
        el : null,
        cb : null,
    
        bind : function(el, cb) {
            this.el = el;
            this.cb = cb;
            this.el.addEventListener('click', this.handler.bind(this), true);
        },
    
        unbind : function() {
            console.log('unbind');
            this.el.removeEventListener('click', this.handler, true);
        },
       
        handler : function() {
            this.cb();
            this.unbind();
        }
    }
};

var manager = {
    init : function() {
        var c = document.getElementById('c');
        controls.game.bind(c, this.action.bind(this));
    },

    action : function() {
        console.log('c clicked');
    }
};
manager.init();

And yet if I remove the event this way it works:

(...)

bind : function(el, cb) {
    this.el = el;
    this.cb = cb;
    var self = this;
    this.el.addEventListener('click', function() {
        self.cb();
        self.el.removeEventListener('click', arguments.callee, true);
    }, true);
}

(...)
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

.bind returns a new function. this.handler.bind(this) !== this.handler! You would have to store a reference to the new function somehow.

For example, storing a reference in a variable and using a closure:

var handler = this.handler.bind(this);
this.el.addEventListener('click', handler, true);

this.unbind = function() {
    this.el.removeEventListener('click', handler, true);
}

As alternative to arguments.callee, you could also give the function a name:

this.el.addEventListener('click', function handler() {
    self.cb();
    self.el.removeEventListener('click', handler, true);
}, true);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...