Edited at

フォーム以外の要素でキーボードイベント(keydown/keypress/keyup)やfocus疑似クラスを使う方法

More than 1 year has passed since last update.


TL;DR

要素にtabindex属性をつける


全ての要素でキーボードイベントが発生するわけではない

WindowsのエクスプローラーやMacのFinderのファイルリストのように、クリックするとアイテムがアクティブになり、カーソルキーの上下で選択位置を移動するUIを作ろうとして、下記のようなマークアップをしたのですが、LI要素でkeyupなどのイベントが取得できませんでした。

<ul>

<li class="list-item is-active">foo</li>
<li class="list-item">bar</li>
<li class="list-item">baz</li>
</ul>

調べてみたら、キーボードイベントは「フォーカスが当たっている要素でないと発生しない1」とのこと。

試しに次のようなCSSを追加してみましたが、クリックしても太字になりませんでした。

.list-item:focus {

font-weight: bold;
}


フォーカスさせるには

次に任意の要素をフォーカス可能にする方法を調べたら、こちらのページを見つけ、tabindexを設定すればよいことが分かりました。


  • タブキーでフォーカスを移動したい場合は、0以上の数値

  • クリックでのフォーカスのみを有効にしたい場合はマイナスの数値


  • tabindex=""は意味がない(Firefoxでは有効)

自分のマークアップにtabindexをつけたところ、:focusのスタイルが適用され、キーボードイベントも発生するようになりました。

<ul>

<li tabindex="-1" class="list-item is-active">foo</li>
<li tabindex="-1" class="list-item">bar</li>
<li tabindex="-1" class="list-item">baz</li>
</ul>





  1. ブラウザの履歴を確認したのですが、情報元のサイトを見つけられませんでした。ちなみにW3CのKeyboardEventにはKeyboard events are commonly directed at the element that has the focus.とだけ書かれています。