如何向实例方法添加事件监听器

4

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

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。看起来好像类的方法并没有被运行,而是一个副本(?)。我还尝试在key_press()内部运行另一个实例函数,但它说该函数未定义。
感谢任何帮助。

根据我的看法,NaN来自于这一行代码 console.log(this.keys_pressed); 而你的代码工作得很好。请在此查看:https://jsfiddle.net/manektech/g8qzs0vm/1/ - Mayank Dudakiya
2个回答

3
当你向窗口或DOM的任何元素添加事件监听器时,this值指向该元素而不是Player实例。因此,由于窗口没有keys_pressed属性,你会得到NaN,并且keys_pressed += 1被视为keys_pressed = undefined + 1,其结果为NaN。为了解决这个问题,我们需要显式地将bind绑定到Player实例上。

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">

我们也可以使用一个箭头函数(=>),它可以捕获当前上下文中的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">


@Sealestr 如果这个答案解决了您的问题,请接受它! - Fullstack Guy

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">


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接