在javascript中检测按键的最简单方法[关闭]

Posted

技术标签:

【中文标题】在javascript中检测按键的最简单方法[关闭]【英文标题】:How do I detect keypresses in Javascript? 【发布时间】:2013-04-11 22:47:35 【问题描述】:

我有一个 javascript 游戏的想法(我将使用 EaselJS 制作它),我必须检测按键。在互联网上环顾四周后,我看到了很多建议(使用 window.onkeypress,使用 jQuery 等),但几乎每个选项都有反对意见。你们有什么建议?使用 jQuery 听起来很容易,但我几乎没有使用该库的经验(而且我也不是 javascript 的资深人士)所以我宁愿避免使用它。如果 jQuery 是最好的选择,有人可以举一个很好的例子(解释会很棒)吗?

我想这被问了很多,但我找不到任何明确的答案。提前致谢!

【问题讨论】:

我建议只听 keypress 事件,或者可能是它的对应事件之一(keydown 或 keyup) 从这里开始 - api.jquery.com/keypress jQuery JavaScript;唯一的区别是 jQuery 是一个抽象出跨浏览器差异的 ,以便更容易(但不一定更高效)编写跨浏览器代码。 我建议这个:github.com/madrobby/keymaster 【参考方案1】:

使用纯 Javascript,最简单的是:

document.onkeypress = function (e) 
    e = e || window.event;
    // use e.keyCode
;

但是有了这个,你只能为事件绑定一个处理程序。

此外,您可以使用以下方法将多个处理程序潜在地绑定到同一事件:

addEvent(document, "keypress", function (e) 
    e = e || window.event;
    // use e.keyCode
);

function addEvent(element, eventName, callback) 
    if (element.addEventListener) 
        element.addEventListener(eventName, callback, false);
     else if (element.attachEvent) 
        element.attachEvent("on" + eventName, callback);
     else 
        element["on" + eventName] = callback;
    

在任何一种情况下,keyCode 在浏览器中都不一致,因此需要检查和找出更多内容。注意 e = e || window.event - 这是 Internet Explorer 的一个正常问题,将事件放在 window.event 中,而不是将其传递给回调。

参考资料:

https://developer.mozilla.org/en-US/docs/DOM/Mozilla_event_reference/keypress https://developer.mozilla.org/en-US/docs/DOM/EventTarget.addEventListener

使用 jQuery:

$(document).on("keypress", function (e) 
    // use e.which
);

参考:

http://api.jquery.com/on/

除了 jQuery 是一个“大型”库之外,jQuery 确实有助于解决浏览器之间的不一致问题,尤其是窗口事件……这是不可否认的。希望很明显,我为您的示例提供的 jQuery 代码更优雅、更短,但以一致的方式完成了您想要的。您应该能够相信e(事件)和e.which(键码,用于知道按下了哪个键)是准确的。在纯 Javascript 中,除非您执行 jQuery 库内部所做的所有事情,否则很难知道。

注意有一个keydown 事件,它不同于keypress。你可以在这里了解更多信息:onKeyPress Vs. onKeyUp and onKeyDown

至于建议使用什么,如果您准备学习该框架,我肯定会建议使用 jQuery。同时,我想说你应该学习 Javascript 的语法、方法、特性以及如何与 DOM 交互。一旦你理解了它是如何工作的以及发生了什么,你应该更容易使用 jQuery。对我来说,jQuery 让事情变得更加一致和简洁。最后,它是 Javascript,并包装了语言。

另一个非常有用的 jQuery 例子是 AJAX。浏览器与 AJAX 请求的处理方式不一致,因此 jQuery 将其抽象化,因此您不必担心。

以下几点可能有助于做出决定:

http://www.jscripters.com/jquery-disadvantages-and-advantages/

【讨论】:

如果您要实现跨浏览器兼容性,您可能还需要联系attachEvent()(顺便说一下,这不是我的反对意见)。 @DavidThomas 我不担心投反对票,我宁愿表达正确的观点。答案更好吗?我很乐意添加/更改任何内容 看起来不错,感谢您的解释!我想我会使用 jQuery,我一直在研究它,我想如果我学会使用它,它无论如何都会让我受益。 我认为值得注意的是 keypress 在我的情况下不起作用,所以我不得不使用 keydown @WilliamJones 那是因为它已被弃用!我刚刚检查了文档,并感到惊讶:developer.mozilla.org/en-US/docs/Web/API/Document/…。【参考方案2】:

KEYPRESS(回车键)在 sn-p 内部单击并按回车键。

原版

document.addEventListener("keypress", function(event) 
  if (event.keyCode == 13) 
    alert('hi.');
  
);

原版速记 (ES6)

this.addEventListener('keypress', event => 
  if (event.keyCode == 13) 
    alert('hi.')
  
)

jQuery

$(this).on('keypress', function(event) 
  if (event.keyCode == 13) 
    alert('hi.')
  
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

jQuery 经典

$(this).keypress(function(event) 
  if (event.keyCode == 13) 
    alert('hi.')
  
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

jQuery 速记 (ES6)

$(this).keypress((e) => 
  if (e.keyCode == 13)
    alert('hi.')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

更短 (ES6)

$(this).keypress(e=>
  e.which==13?
  alert`hi.`:null
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

由于一些要求,这里有一个解释:

我重写了这个答案,因为随着时间的推移,事情已经被弃用,所以我更新了它,因为 cmets 中的一些人说它“bla-bla”太多了。它不是关于“keydown”,而是关于“keypress”。所以像“Esc”这样的非字符键不应该那样工作。

我使用this 在文档准备好时专注于结果内的窗口范围,为了简洁起见,但这不是必需的。

已弃用:.which.keyCode 方法实际上被认为已弃用,所以我会推荐 .code 但我个人仍然使用 keyCode,因为性能要快得多,只有这对我来说很重要。 jQuery 经典版本.keypress() 并没有像某些人所说的那样被正式弃用,但它们不像.on('keypress') 那样更受欢迎,因为它具有更多功能(实时状态、多个处理程序等)。 原版版本中的 'keypress' 事件也已弃用。今天人们应该更喜欢beforeinput 或keydown、keyup

性能: 越快越好。这就是为什么我更喜欢.keyCode,即使它被认为已弃用(在大多数情况下)。不过,这完全取决于您(2020 年提交)。

Performance Test

【讨论】:

关于document.addEventListener("keypress", function(event):好的,但是为什么我不能“捕获” [Esc] 键? 因为 [Esc] 键应该与 "keydown" 一起使用。我说它已被弃用的原因......仔细阅读。最好将keypress 用于ASCII 字符(D、L、%、1、Ä 等),将keydown 用于非字符键(箭头键、Esc、Alt、Ctrl、Page up/down 等)。随着时间的推移,事情可能会发生变化...... 谢谢你,@ Thielicious。我想我已经做到了。但是我也没有看到我最后给你的回复!至少不在这里,而且 我当然没有删除它! 似乎不是其他人这样做了,或者 我看不到他们(尽管这可能很奇怪声音) ! (此外,如果我删除我的消息,你会回复他们吗?无论如何,再次感谢!(我希望这能得到解决!)【参考方案3】:

使用 event.key 和现代 JS!

没有数字代码了。您可以直接使用"Enter""ArrowLeft""r" 或任何键名,让您的代码更具可读性。

注意:旧的替代方案(.keyCode.which)已弃用。

document.addEventListener("keypress", function onEvent(event) 
    if (event.key === "ArrowLeft") 
        // Move Left
    
    else if (event.key === "Enter") 
        // Open Menu...
    
);

Mozilla Docs

Supported Browsers

【讨论】:

方向键实际上是“ArrowUp”、“ArrowDown”、“ArrowRight”、“ArrowLeft” 为什么我不能“捕获”这些箭头键或 [Esc] 键? “捕捉”媒体:***.com/a/46210516/974045【参考方案4】:

有几种方法可以解决这个问题; Vanilla JavaScript 可以很好地做到这一点:

function code(e) 
    e = e || window.event;
    return(e.keyCode || e.which);

window.onload = function()
    document.onkeypress = function(e)
        var key = code(e);
        // do something with key
    ;
;

或者更结构化的处理方式:

(function(d)
    var modern = (d.addEventListener), event = function(obj, evt, fn)
        if(modern) 
            obj.addEventListener(evt, fn, false);
         else 
            obj.attachEvent("on" + evt, fn);
        
    , code = function(e)
        e = e || window.event;
        return(e.keyCode || e.which);
    , init = function()
        event(d, "keypress", function(e)
            var key = code(e);
            // do stuff with key here
        );
    ;
    if(modern) 
        d.addEventListener("DOMContentLoaded", init, false);
     else 
        d.attachEvent("onreadystatechange", function()
            if(d.readyState === "complete") 
                init();
            
        );
    
)(document);

【讨论】:

好的,但为什么我不能“捕获”[Esc] 键?【参考方案5】:

不要过于复杂。

  document.addEventListener('keydown', logKey);
    function logKey(e) 
      if (`$e.code` == "ArrowRight") 
        //code here
      
          if (`$e.code` == "ArrowLeft") 
        //code here
      
          if (`$e.code` == "ArrowDown") 
        //code here
      
          if (`$e.code` == "ArrowUp") 
        //code here
      
    

【讨论】:

恭喜! 这个答案应该得到所有的功劳!除了是唯一一个可以“捕获”箭头键和 [Esc] 键的地方,所有早期的代码都失败了(至少对于我),如果实际捕获所有键盘键,甚至状态键! 还有一件事:我该如何移除这个事件监听器?我尝试使用document.removeEventListener(),但它不起作用:监听器继续处于活动状态,即键盘继续被监控! 虽然这个答案可能不是 OP 正在寻找的,因为它只是关于按键(即使按键通常被弃用并且新事件如 keydown/keyup/beforeinput 派上用场,问题是 8岁),但我仍然可以补充说,当您按住键时,keydown 会不断触发事件,这并不总是很好。因此,请添加 event.repeat = false 以防止这种情况发生。

以上是关于在javascript中检测按键的最简单方法[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

在 Linux 中检测 CDROM 介质移除/插入的最简单方法是啥

在PHP中检测移动设备的最简单方法

检测图像中矩形的最简单*正确*方法是啥?

检测夹点的最简单方法

从终端检测脚本中键盘输入的最简单方法是啥?

在 .NET 应用程序中查看所有调用的最简单方法(分析/检测)