【问题标题】:Capture key press without placing an input element on the page?捕获按键而不在页面上放置输入元素?
【发布时间】:2011-02-22 04:00:21
【问题描述】:

如何在 JavaScript 中不在页面上放置输入元素的情况下捕获按键,例如 Ctrl+Z?好像在IE中,keypress和keyup事件只能绑定到输入元素(输入框,textareas等)

【问题讨论】:

  • @Tim:因为当GUI元素不在焦点时按下这些组合键时执行操作是非常规的,因此违反了最小惊喜原则。
  • @Tomalak:还有其他一些元素可能需要处理关键事件,例如<canvas>,尽管我同意任何这样的元素都应该在发出键之前被强制占据焦点事件。使用tabindex 属性将使元素能够接收焦点,如果它无法获得焦点。
  • 我会推荐 Keypress javascript 库:dmauro.github.io/Keypress
  • 捕获键盘输入的另一个原因是,如果您只在屏幕上显示条形码并使用条形码扫描仪作为键盘输入。我在做什么。
  • 大多数应用程序都有没有输入焦点的键盘快捷键。常识。以 CTRL-Z 表示 UNDO 为例。

标签: javascript


【解决方案1】:

对于不可打印的键,例如箭头键和快捷键,例如 Ctrl-z、Ctrl-x、Ctrl-c,它们可能会触发浏览器中的某些操作(例如,在可编辑的文档或元素中),您可能不会在所有浏览器中获取按键事件。因此,如果您对禁止浏览器的默认操作感兴趣,则必须改用keydown。如果没有,keyup 也可以。

将keydown 事件附加到document 适用于所有主要浏览器:

document.onkeydown = function(evt) {
    evt = evt || window.event;
    if (evt.ctrlKey && evt.keyCode == 90) {
        alert("Ctrl-Z");
    }
};

如需完整参考,我强烈推荐Jan Wolter's article on JavaScript key handling。

【讨论】:

  • @hendrik:我不明白为什么它不应该,但我目前无法测试它。
【解决方案2】:

jQuery 也有一个非常容易使用的优秀实现。以下是跨浏览器实现此功能的方法:

$(document).keypress(function(e){
    var checkWebkitandIE=(e.which==26 ? 1 : 0);
    var checkMoz=(e.which==122 && e.ctrlKey ? 1 : 0);

    if (checkWebkitandIE || checkMoz) $("body").append("<p>ctrl+z detected!</p>");
});

在 IE7、Firefox 3.6.3 和 Chrome 4.1.249.1064 中测试

另一种方法是使用 keydown 事件并跟踪 event.keyCode。然而,由于 jQuery 使用 event.which 规范化 keyCode 和 charCode,他们的规范建议在各种情况下使用 event.which:

$(document).keydown(function(e){
if (e.keyCode==90 && e.ctrlKey)
    $("body").append("<p>ctrl+z detected!</p>");
});

【讨论】:

  • 不知道 e.which 可以捕捉击键和鼠标点击!你能告诉我如何获得密钥代码 26 吗?
  • keycode 26 是由按键事件设置的“which”的特定 id(表示 CTRL+z)。要查看按键事件的更多字符映射,请查看 the jQuery docs 或 unixpapa's key event tester
  • 谢谢。我知道键码是什么意思。我的意思是,17 代表 Ctrl,90 代表 Z,那么你是如何得到数字 26 的?我只是用谷歌搜索,但找不到答案。
  • 使用我在评论中添加的链接来测试不同击键的代码。
  • 您不会在所有浏览器中获得 26。事实上,在 WebKit 中你只得到 26 个。不在 IE、Firefox 或 IE 中。
【解决方案3】:

对于现代 JS,使用 event.key!

document.addEventListener("keypress", function onPress(event) {
    if (event.key === "z" && event.ctrlKey) {
        // Do something awesome
    }
});

注意:旧属性(.keyCode 和 .which)已弃用。

Mozilla Docs

Supported Browsers

【讨论】:

  • 可能值得补充一下为什么现在应该更改所有旧代码,“现代 JS”方法有什么优势,尤其是当“ old"/traditional/standard 方法具有更广泛的浏览器支持。
【解决方案4】:

检测按键,包括组合键:

window.addEventListener('keydown', function (e) {
  if (e.ctrlKey && e.keyCode == 90) {
    // Ctrl + z pressed
  }
});

这样做的好处是您不会 覆盖任何全局属性,而只是引入了副作用。不好,但绝对比这里的其他建议要邪恶得多。

【讨论】:

    【解决方案5】:

    编码和检测 ctrl+z

    document.onkeyup = function(e) {
      if(e.ctrlKey && e.keyCode == 90) {
        // ctrl+z pressed
      }
    }
    

    【讨论】:

      【解决方案6】:

      将侦听器附加到keydown 事件而不是keypress,因为后者是is now deprecated。

      window.addEventListener('keydown', keyDownHandler);
      

      keydown 事件在按键被按下时连续触发。如果你想让它只触发一次,在处理程序内部使用event.repeat 属性:

      keyDownHandler(event) {
           if (!event.repeat) {
               <code here will only be executed once while the key is pressed>
           }
      }
      

      记住在不再需要时删除监听器。

      window.removeEventListener('keydown', keyDownHandler);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-20
        • 1970-01-01
        • 2011-10-23
        • 2023-04-11
        • 2021-11-24
        • 2011-08-21
        • 1970-01-01
        • 2011-09-04
        相关资源
        最近更新 更多