jQuery keypress,keydown,keyup black magic(Macs)背后的理论是什么?

Sag*_*ual 49 macos jquery keypress keydown keyup

我对keypress,keydownkeyup的各种行为感到困惑.似乎我错过了一个重要的文档,一个解释了这个三重奏的细微之处和细微差别.有人可以帮我弄清楚我需要阅读哪个文件才能更有效地使用这些事件吗?如果您需要详细信息,请参阅下文.

@ov:你让我展示一些代码,但这并不是我试图解决的代码中的特定问题.我正在尝试处理这些事件处理程序的行为,并要求了解它们的人指出一个好的文档.

我使用jQuery构建输入表单并将其插入到我的文档中.它工作得很好,大多数情况下.我希望表单像我在其中看到的大多数其他输入表单一样响应键盘:esc键应该忽略表单与单击取消按钮相同,并且因为表单上有一个<textarea>,cmd+ enter应该与单击时相同确定按钮.使用按键事件似乎很简单.问题是Chrome不会为密钥或+ 调用我的按键处理程序.它会激发+ 和+ 以及字母数字,但不是+ .esccmdenterctrlenteroptionentercmdenter

所以我会改用密钥.我得到KEYUPesc,和KEYUPcmd,和KEYUPenter,伟大的.但我没有得到KEYUPenter,而我按住键cmd.

第三次是魅力,你可能会认为keydown似乎工作,但有了keydown,你会得到重复键.我知道,你所要做的就是在第一次调用时解除处理程序的绑定,但三种不同的事件类型表现得如此不同似乎很奇怪.为什么是这样?那里有一个明显的文件,我显然还没读过吗?

Cha*_*ase 89

Keypress:


当浏览器注册键盘输入时,按键事件将发送到元素.这类似于keydown事件,除了密钥重复的情况.如果用户按下并按住键,则会触发一次 keydown事件,但会为每个插入的字符触发单独的按键事件.此外,修饰键(如Shift)会触发keydown事件,但不会触发keypress 事件.

Keydown:


当用户首次按下键盘上的键时,keydown事件将发送到元素.它可以附加到任何元素,但事件仅发送到具有焦点的元素.可聚焦元素可以 在浏览器之间变化,但是表单元素总是可以获得焦点,因此这种事件类型是合理的候选者.

关键字:


当用户在键盘上释放键时,键盘事件被发送到元素.它可以附加到任何元素,但事件仅发送到具有焦点的元素.可聚焦元素可以在浏览器之间变化,但是表单元素总是可以获得焦点,因此这种事件类型是合理的候选者.

此外,这是一个方便的信息,通常掩盖:


如果需要捕获任何位置的按键(例如,在页面上实现全局快捷键),将此行为附加到文档对象会很有用.由于事件冒泡,除非明确停止,否则所有按键操作都将使DOM向上移动到文档对象.

要确定输入了哪个字符,请检查传递给处理函数的事件对象.虽然浏览器使用不同的属性来存储此信息,但jQuery会规范化.which 属性,以便您可以可靠地使用它来检索字符代码.

请注意,keydown和keyup提供一个代码,指示按下哪个键,而keypress指示输入了哪个字符.例如,小写的"a"将通过keydown和keyup报告为65,但是按key按97报告.所有事件都将大写的"A"报告为65.由于这种区别,当捕获箭头键,.keydown()或.keyup()等特殊键击时是更好的选择.

有关cmdMAC密钥的更多信息:命令密钥的jQuery密钥代码


Ter*_*rry 5

这篇文章是一个很好的资源解释之间的差异keyup,keydownkeypress.

简短的回答是除了考虑不同的浏览器之外,没有简单的方法来处理它们.

我在我编写Bootstrap插件中亲自处理它的方式是创建一个自定义方法来检查支持哪个事件.巧合的是,不久之后,一个非常类似的方法出现在官方的Bootstrap版本中:P

//------------------------------------------------------------------
//
//  Check if an event is supported by the browser eg. 'keypress'
//  * This was included to handle the "exhaustive deprecation" of jQuery.browser in jQuery 1.8
//
eventSupported: function(eventName) {         
    var isSupported = (eventName in this.$element);

    if (!isSupported) {
      this.$element.setAttribute(eventName, 'return;');
      isSupported = typeof this.$element[eventName] === 'function';
    }

    return isSupported;
}
Run Code Online (Sandbox Code Playgroud)

稍后我在我的代码中使用它来附加事件处理程序:

if (this.eventSupported('keydown')) {
  this.$element.on('keydown', $.proxy(this.keypress, this));
}
Run Code Online (Sandbox Code Playgroud)