为什么我的 DIV 在获得焦点时不捕获按键事件?

Why isn't my DIV capturing keypress events when it has the focus?

我正在使用 jQuery 1.12。我想要一个 DIV 在它具有焦点时捕获按键(具体来说,向下和向上箭头)。所以我跟着这个

 $('div.select-styled').bind('keydown', function(event) {
    console.log(event.keyCode);
    elt = $(this).search(".select-options li:hover");
    console.log(elt);
    switch(event.keyCode){
    // case up
    case 38:
        console.log(“up pressed.”)
        break;
    case 40:
        console.log(“down pressed”)
        break;
    }
 });

但这不是捕获按键。在这里查看我的 Fiddle — http://jsfiddle.net/cwzjL2uw/10/ 。单击“Select State”菜单,或单击“Last Name”字段并单击“Tab”将焦点移至下一个 DIV。但是,当该菜单具有焦点时,单击任何键都不会激活上面的处理程序,至少在 Mac Chrome 或 Firefox 上它不会激活。

感谢您的帮助,-

为您的 .select-styled 元素提供 tabindex 属性(例如:tabindex="1")将允许它接收 JavaScript 键盘事件。


解释: jQuery API for .keydown() 提到它只适用于可聚焦元素:

It can be attached to any element, but the event is only sent to the element that has the focus. Focusable elements can vary between browsers, but form elements can always get focus so are reasonable candidates for this event type.

根据此 previous Stack Overflow answer, <div> elements are not focusable by default, but DOM Level 2 HTML 声明,除其他规则外,任何具有 tabindex 的元素都可以获得焦点:

Today's browsers define focus() on HTMLElement, but an element won't actually take focus unless it's one of:

  • HTMLAnchorElement/HTMLAreaElement with an href
  • HTMLInputElement/HTMLSelectElement/HTMLTextAreaElement/HTMLButtonElement but not with disabled (IE actually gives you an error if you try), and file uploads have unusual behaviour for security reasons
  • HTMLIFrameElement (though focusing it doesn't do anything useful). Other embedding elements also, maybe, I haven't tested them all.
  • Any element with a tabindex

或者,这可能是更好的做法,您可以简单地将 keydown 事件处理程序绑定到 $(document) 当元素接收到 focus(您的 jQuery 已经可以毫无问题地处理),并在 blur.

上解除绑定

问题是,当您按 tab 时,焦点在 .select 而不是 .select-styled div element,因为 .select 是父级其中包含其余元素。因此,您可能需要将 keydown 绑定到 .select.

$(".select").on('keydown',function(event) {
    console.log(event.keyCode);
    elt = $(this).search(".select-options li:hover");
    console.log(elt);
    switch(event.keyCode){
    // case up
    case 38:

        break;
    case 40:
        break;
    }
});

这是Updated Fiddle