最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Bind object instance to the "this" keyword in addEventListener function - Stack Overflow

programmeradmin5浏览0评论

I have a class for an editor that attaches menus and events when enabled. I want to capture keyboard events related to this editor, which trigger functions within the object instance when pressed. The following works as intended, making the ' key toggle an editor element:

var edit = null;

class editor {
    constructor() {
        this.element = document.createElement("div");

        addEventListener("keydown", function(event) {
            if(event.key == "`") {
                edit.toggle();
            }
        });
    }

    toggle() {
        if(root.contains(this.element)) {
            document.body.removeChild(this.element);
        } else {
            document.body.appendChild(this.element);
        }
    }
}

edit = new editor();

The problem is I can't make addEventListener call the this.toggle function of the object: I tried using bind but nothing I did works, I can't make the event listener carry the object reference when using the this keyword. As such I store my object in a global var and have the object's internal functions call itself through that var, which feels like a messy and wrong way to do it, especially if I decide to use multiple instances in which case the reference would need to be unique. Here's a version that gets close to what I'm trying to achieve but won't work:

class editor {
    constructor() {
        this.element = document.createElement("div");

        addEventListener("keydown", function(event) {
            if(event.key == "`") {
                this.toggle();
            }
        }).bind(this);
    }

    toggle() {
        if(root.contains(this.element)) {
            document.body.removeChild(this.element);
        } else {
            document.body.appendChild(this.element);
        }
    }
}

new editor();

I have a class for an editor that attaches menus and events when enabled. I want to capture keyboard events related to this editor, which trigger functions within the object instance when pressed. The following works as intended, making the ' key toggle an editor element:

var edit = null;

class editor {
    constructor() {
        this.element = document.createElement("div");

        addEventListener("keydown", function(event) {
            if(event.key == "`") {
                edit.toggle();
            }
        });
    }

    toggle() {
        if(root.contains(this.element)) {
            document.body.removeChild(this.element);
        } else {
            document.body.appendChild(this.element);
        }
    }
}

edit = new editor();

The problem is I can't make addEventListener call the this.toggle function of the object: I tried using bind but nothing I did works, I can't make the event listener carry the object reference when using the this keyword. As such I store my object in a global var and have the object's internal functions call itself through that var, which feels like a messy and wrong way to do it, especially if I decide to use multiple instances in which case the reference would need to be unique. Here's a version that gets close to what I'm trying to achieve but won't work:

class editor {
    constructor() {
        this.element = document.createElement("div");

        addEventListener("keydown", function(event) {
            if(event.key == "`") {
                this.toggle();
            }
        }).bind(this);
    }

    toggle() {
        if(root.contains(this.element)) {
            document.body.removeChild(this.element);
        } else {
            document.body.appendChild(this.element);
        }
    }
}

new editor();
Share Improve this question asked Mar 23 at 17:53 MirceaKitsuneMirceaKitsune 1,1511 gold badge11 silver badges17 bronze badges 2
  • 1 The issue can probably be fixed, but I think that you could help yourself a lot, not using a generic class, and instead use custom elements. – chrwahl Commented Mar 23 at 19:04
  • 4 It's addEventListener("keydown", function(event) {…}.bind(this)) not addEventListener("keydown", function(event) {…}).bind(this) – Bergi Commented Mar 23 at 19:54
Add a comment  | 

1 Answer 1

Reset to default 4

You're not binding the callback function (which is where you want to use this), you're binding the addEventListener function itself (and discarding the result).

Either bind the callback:

addEventListener("keydown", function(event) {
  if(event.key == "`") {
    this.toggle();
  }
}.bind(this));

Or use arrow functions:

addEventListener("keydown", event => {
  if(event.key == "`") {
    this.toggle();
  }
});
发布评论

评论列表(0)

  1. 暂无评论