如何将Eventlistener添加到实例方法

时间:2019-03-26 04:42:33

标签: javascript canvas ecmascript-6 addeventlistener

我有一个想要在事件发生时运行函数的类。每当该函数调用时,该类实例的函数就不会运行。

class Player {
    constructor() {
        window.addEventListener('keypress', this.key_press);
        this.keys_pressed = 0;
    }

    key_press(key_press) {
        if(key_press.key == "w") {
            console.log(key_press);
            this.keys_pressed += 1;
        }
        console.log(this.keys_pressed);
    }
}

无论何时调用this.key_press,它都会注销NaN。似乎该类的方法没有在运行,而是在运行copy(?)。我也尝试过在key_press()内运行另一个实例函数,但它表示该函数未定义。

感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

将事件侦听器添加到window或DOM的任何元素时,this值指向该元素而不是Player实例。

因此,您得到NaN,因为window不具有keys_pressed属性,并且keys_pressed += 1被视为keys_pressed = undefined + 1,即NaN

要解决此问题,我们需要明确地bindPlayer实例:

const input = document.querySelector("#input");
class Player {
    constructor() {
        input.addEventListener('keypress', this.key_press.bind(this));
        this.keys_pressed = 0;
    }

    key_press(key_press) {
        if(key_press.key == "w") {
            this.keys_pressed += 1;
        }
        console.log(this.keys_pressed);
    }
}
let p = new Player();
Type here: <input type="text" id="input">

我们还可以使用 arrow ( => )函数,该函数从当前上下文中捕获this,并指向Player对象的当前实例:

const input = document.querySelector("#input");
class Player {
    constructor() {
        input.addEventListener('keypress', (event) => this.key_press(event));
        this.keys_pressed = 0;
    }

    key_press(key_press) {
        if(key_press.key == "w") {
            this.keys_pressed += 1;
        }
        console.log(this.keys_pressed);
    }
}
let p = new Player();
Type here: <input type="text" id="input">

答案 1 :(得分:0)

这是onkeypress和bind的另一种解决方法。

class Player {
    constructor(input) {
        input.onkeypress = this.onkeyPress.bind(this); 
        this.keys_pressed = 0;
    }
    onkeyPress(event) {
      event.key=="w"? this.keys_pressed++:this.keys_pressed;
      console.log(this.keys_pressed);
    };
}

const input = document.querySelector("#input");
let p = new Player(input);
Type here: <input type="text" id="input">