Javascript 防止按钮在按住时持续触发

Javascript 防止按钮在按住时持续触发,javascript,controls,dom-events,Javascript,Controls,Dom Events,我试图阻止特定的按钮持续触发,但我的任何方法都没有成功。我尝试了其他stackoverflow帖子中的一些建议/答案,但都没有奏效。我目前有一个控制器,对于我的左/右按钮,我不在乎它们是否重复,但对于我的跳转按钮,我不希望能够按住按钮并让角色继续跳转。我最接近完成这项工作的方法是使用地图并将按钮设置到地图上,但不幸的是,在keyup上,角色也会跳跃。这是我目前的代码: class Controller { constructor() { this.left = fals

我试图阻止特定的按钮持续触发,但我的任何方法都没有成功。我尝试了其他stackoverflow帖子中的一些建议/答案,但都没有奏效。我目前有一个控制器,对于我的左/右按钮,我不在乎它们是否重复,但对于我的跳转按钮,我不希望能够按住按钮并让角色继续跳转。我最接近完成这项工作的方法是使用地图并将按钮设置到地图上,但不幸的是,在
keyup
上,角色也会跳跃。这是我目前的代码:

class Controller {
    constructor() {
        this.left  = false;
        this.up    = false;
        this.right = false;
        this.down  = false;
        this.pressed = {};

        let keyDown = (e) => {
            if (e.code == 'ArrowLeft')  this.left = true;
            if (e.code == 'ArrowRight') this.right = true;
            if (e.code == 'ArrowDown')  this.down = true;
           
            if (e.code === 'ArrowUp') {
                if (this.pressed[e.code] === false) { return }
                else {
                    this.pressed[e.code] = false;
                    this.up = true;
                }
            } 
        }
        let keyUp = (e) => {
            if (e.code == 'ArrowLeft')  this.left = false;
            if (e.code == 'ArrowRight') this.right = false;
            if (e.code == 'ArrowDown')  this.down = false;
            if (e.code === 'ArrowUp') {
                this.pressed[e.code] = true;
                this.up = false;
            }
        }
    window.addEventListener('keydown', keyDown);
    window.addEventListener('keyup', keyUp);
   }
   
}
let controller = new Controller();
还有一些我也试过的替代品

        this.pressed = false;
        let keyDown = (e) => {
            if (e.code == 'ArrowLeft')  this.left = true;
            if (e.code == 'ArrowRight') this.right = true;
            if (e.code == 'ArrowDown')  this.down = true;
            console.log(controller.pressed)
            if (e.code === 'ArrowUp') {
                if (!this.pressed) { return }
                this.pressed = false;
                this.up = true;
            } 
        }
        let keyUp = (e) => {
            if (e.code == 'ArrowLeft')  this.left = false;
            if (e.code == 'ArrowRight') this.right = false;
            if (e.code == 'ArrowDown')  this.down = false;
            if (e.code === 'ArrowUp') {
                this.pressed = true;
                this.up = false;
            }
        }
从逻辑上讲,我觉得这些应该有效,但它们没有。如果有关系的话,我的角色会基于此进行跳跃

if (controller.up && !this.jumping) {this.vy -= this.speed * 60; this.jumping = true;}
我可能尝试过至少10种不同的方法,最接近的是我的角色在停下来之前跳了两次(同时举起箭头)

编辑:这将提供2次跳跃,然后停止。有人能解释为什么他在停车前跳了两次吗

this.keySet = new Set();

        let keyDown = (e) => {
            if (e.code == 'ArrowUp') {
                if (this.keySet.has(e.code)) { this.up = false } 
                else { this.keySet.add(e.code); this.up = 'keydown' === e.type }
            }            
        }
        let keyUp = (e) => {
            if (e.code == 'ArrowUp') { this.keySet.delete(e.code); this.up = false }            
        }
您可以使用该函数

节流的工作方式是,当您调用函数时,它将像正常一样执行该函数,但在后续调用中,它将不会再次运行,直到上次尝试执行后经过足够的时间


Lodash有一个实现,但你可以在互联网上找到它的各种版本:

让controller=new controller()
可能会多次触发,这会创建许多
controller
的实例,而每个controller都会创建新的
按键
事件侦听器。我不明白这是怎么回事。当使用一个类时,我必须通过这样做来创建它的一个实例,否则我根本就没有控制器。我不认为这是我想要的。应该有一种方法可以通过控制器功能实现这一点,而无需节流。
this.keySet = new Set();

        let keyDown = (e) => {
            if (e.code == 'ArrowUp') {
                if (this.keySet.has(e.code)) { this.up = false } 
                else { this.keySet.add(e.code); this.up = 'keydown' === e.type }
            }            
        }
        let keyUp = (e) => {
            if (e.code == 'ArrowUp') { this.keySet.delete(e.code); this.up = false }            
        }