【问题标题】:JS keylogger not accepting keyup correctlyJS 键盘记录器没有正确接受键盘输入
【发布时间】:2017-10-10 17:29:58
【问题描述】:

我对 JS 很陌生,所以我可能会犯一些愚蠢的错误,但我的键盘记录器似乎无法正常运行。它正确地接受多个击键,但是当一个被释放时,它会将两者都识别为启动。有什么帮助吗?

这是我的代码:

var keymap = {};

onkeydown = onkeyup = function(e){
    keymap[e.keyCode] = e.type == 'keydown';

    if(keymap[39] && keymap[32]){ // Right+Space
        jumpRight();

    }

    if(keymap[37] && keymap[32]){ // Left+Space
        jumpLeft();

    }

    if(keymap[32]){ // Space
        jump();

    }

    if(keymap[39]){ // Right
        right();

    }

    if(keymap[37]){ // Left
        left();

    }
}

我正在使用谷歌浏览器,如果有帮助的话。

谢谢!

【问题讨论】:

  • 这是一种奇怪的方法吗?在编造自己的怪癖之前,您是否考虑过其他解决方案?
  • @adeneo 这个函数对我来说看起来很标准,我已经用过很多次了。 PS:不要低调侮辱少数加入并发布好问题的新人。
  • @Feathercrown - 我不是在侮辱,但这很奇怪。查看代码,正确的做法似乎是将不同的函数绑定到两个事件,并直接使用 keyCode 进行比较。我想我从未见过有人使用像这样的对象(带有数字键?) 来比较键,即使您声称您已经使用过很多次?我的意思是,你到底为什么不直接使用if (e.which === 39) ...
  • @adeneo 好的,是的,它应该是一个数组。至于数组的点,您可以在按下事件之外使用键信息,并访问在当前按下期间按住的键。例如。 h 被按住,然后玩家按下d,现在你可以看到h 是否被这个对象按住。这在画布游戏中很常见。对于一次性的关键反应,您的方法就足够了,而且是首选,因为它不太复杂,但它不允许对键进行完全跟踪。
  • @adeneo 至于使用单独的if 语句,它变得太长了。当您基本上可以用一条线检测所有键时,为什么要使用它们?基本上,数组用于存储,这对于解决这个问题(在问题中)和许多其他问题至关重要,例如跟踪按住的键,并且非if 策略更短并捕获所有键放入数组中,允许通过键码轻松访问,而无需为要检测的每个键添加一行。使用带有自己的 ifs 的单个变量进行存储是可行的,但数组再次更易于使用。

标签: javascript keylogger


【解决方案1】:

我认为它可以正确识别击键,因为数组正在正确更新。问题是您的函数(left()right()jump() 等)仅在按键事件发生时才会触发。当您按住某个键时,有时它会继续触发 keydown 事件,有时则不会。这会导致函数不会触发,即使您的程序知道该键被按下。

工作示例(始终显示数组值,而不仅仅是按键;显示的数组值并不一定意味着函数触发):

var keymap = {};

onkeydown = onkeyup = function(e){
    keymap[e.keyCode] = e.type == 'keydown';

    if(keymap[39] && keymap[32]){ // Right+Space
        jumpRight();

    }

    if(keymap[37] && keymap[32]){ // Left+Space
        jumpLeft();

    }

    if(keymap[32]){ // Space
        jump();

    }

    if(keymap[39]){ // Right
        right();

    }

    if(keymap[37]){ // Left
        left();

    }
}

document.onkeydown=onkeydown;
document.onkeyup=onkeyup;

function jump(){}
function left(){}
function right(){}
function jumpLeft(){}
function jumpRight(){}

setInterval(function(){console.log(keymap[37]," ",keymap[32]," ",keymap[39]);},5);

非工作示例(现在如何,仅在按键上显示数组值;显示数组值 == 函数触发):

var keymap = {};

onkeydown = onkeyup = function(e){
    keymap[e.keyCode] = e.type == 'keydown';

    if(keymap[39] && keymap[32]){ // Right+Space
        jumpRight();

    }

    if(keymap[37] && keymap[32]){ // Left+Space
        jumpLeft();

    }

    if(keymap[32]){ // Space
        jump();

    }

    if(keymap[39]){ // Right
        right();

    }

    if(keymap[37]){ // Left
        left();

    }
}

document.onkeydown=onkeydown;
document.onkeyup=onkeyup;

function jump(){console.log("jump");}
function left(){console.log("left");}
function right(){console.log("right");}
function jumpLeft(){console.log("jumpleft");}
function jumpRight(){console.log("jumpright");}

请注意,在非工作示例中,日志记录仅发生在 keydown 事件上,即调用函数的时间。在“工作”示例中,无论关键事件如何,都会发生日志记录,但您的函数仍然无法触发,因为它们仍然会在关键事件发生时发生。这是一个完整的示例:

var keymap = {};

onkeydown = onkeyup = function(e){
    keymap[e.keyCode] = e.type == 'keydown';
}

document.onkeydown=onkeydown;
document.onkeyup=onkeyup;

function jump(){console.log("jump");}
function left(){console.log("left");}
function right(){console.log("right");}
function jumpLeft(){console.log("jumpleft");}
function jumpRight(){console.log("jumpright");}

function main(){
    if(keymap[39] && keymap[32]){ // Right+Space
        jumpRight();

    }

    if(keymap[37] && keymap[32]){ // Left+Space
        jumpLeft();

    }

    if(keymap[32]){ // Space
        jump();

    }

    if(keymap[39]){ // Right
        right();

    }

    if(keymap[37]){ // Left
        left();

    }
}

setInterval(main,250);

希望这会有所帮助!

祝你学习更多 JS 好运!

P.S.:您将 left() 标记为“空格”。 :P

【讨论】:

  • @Jacob 你是否点击了“运行代码 sn-p”,然后还点击了显示的白色区域(页面)?
  • @Jacob 也欢迎您。还有一件事:keymap 初始化为 [] 比初始化为 {} 更好,因为您使用的是数字键。
  • 哎呀.. 现在可以使用了。谢谢!
猜你喜欢
  • 1970-01-01
  • 2023-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多