jQuery按键,keydown,keyup黑魔法(在Mac上)背后的理论是什么?



我对按键向下键向上键的各种行为感到困惑。我似乎错过了一篇重要的文档,它解释了这三人组的微妙之处。有人能帮我弄清楚我需要阅读哪份文件,以便更有效地使用这些事件吗?如果您需要详细信息,请参阅下文。

@o.v.:你让我展示一些代码,但这并不是我想要解决的代码中的一个特定问题。我试图了解这些事件处理程序的行为,并请了解它们的人给我指一份好的文档。

我使用jQuery构建一个输入表单,并将其插入到我的文档中。大部分情况下,它都很好用。我希望表单能像我看到的大多数其他输入表单一样对键盘做出响应:esc键应该像单击取消按钮一样关闭表单,而且因为表单上有<textarea>cmd+输入定按钮一样。使用按键事件似乎足够简单。问题是,Chrome不会为esc键或cmd+enter键处理程序。它为ctrl+enter和<kbd]选项>>+enter和字母数字触发,但不为cmd+enter

因此,我将使用keyup。我得到esckeyupcmdkeyup入ey up,很棒。但当我按住cmd时,对于回车键,我不会得到键向上

第三次是魅力所在,你可能会认为keydown似乎有效,但使用keydown[/em>,你会得到重复键。我知道,你所要做的就是在第一次被调用时解除处理程序的绑定,但这三种不同的事件类型的行为会如此不同,这似乎很奇怪。为什么会这样?有没有一份我显然没有读过的明显的文件?

按键:


当浏览器注册时,按键事件被发送到元素键盘输入。这类似于keydown事件,除了按键重复的情况。如果用户按住某个键事件被触发一次,但会触发单独的按键事件对于每个插入的字符。此外,修改器键(例如Shift)触发按键按下事件,但不触发按键按下的事件

键控:


当用户第一次按下键。它可以附加到任何元素,但事件仅发送到具有焦点的元素。可聚焦元素可以在浏览器之间各不相同,但表单元素总是可以获得焦点,因此此事件类型的合理候选者。

键控:


当用户在键盘。它可以附加到任何元素,但事件仅发送到具有焦点的元素。可聚焦元素可能有所不同在浏览器之间,但表单元素总是可以获得焦点,因此此事件类型的合理候选者。

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


如果需要捕捉任何按键(例如,实现页面上的全局快捷键),附加此行为很有用到文档对象。由于事件冒泡,所有按键将从DOM向上到达文档对象,除非明确停止。

要确定输入的字符,请检查事件对象传递给处理程序函数。而浏览器使用不同的属性来存储此信息,jQuery将规范化。该属性使您能够可靠地使用它来检索字符代码

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

有关MAC上cmd密钥的更多信息:jQuery命令密钥的密钥代码

本文是解释keyupkeydownkeypress之间差异的好资源。

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

在我编写的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;
}

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

if (this.eventSupported('keydown')) {
this.$element.on('keydown', $.proxy(this.keypress, this));
}

您必须记住,在mac上验证KeyboardEvent时,修饰符键将不会被选为event.ctrlKey,而是event.metaKey。MDN上提供了更多文档。

在没有看到任何代码的情况下,我打赌这就是⌘+Enter没有被选中的原因。