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

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のスタイルが適用され、キーボードイベントも発生するようになりました。


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

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.