キーボードイベントは、ユーザーによるキーボードのアクションのことです。
例えば、特定のキーが押されたらメッセージを表示したり、あるいはどのキーが押されたか確認したい時などにキーボードイベントを活用します。

そこで今回は、キーボードイベントについて解説していきます。

keydownとkeyup

keydownはキーが押された時に発生するイベントで、keyupは押されていたキーが離された時に発生するイベントです。

これらのイベントにおけるバブリングの発生やデフォルト動作のキャンセルは、以下の通りです。

イベント バブリング キャンセル
keydown あり
keyup あり

keydownイベントとkeyupイベントが発生したら、それぞれのイベント名を出力するテストを行ってみます。

<p>Press a key</p>
<textarea id="area"></textarea>

<script>
  let area = document.getElementById('area');
  area.onkeydown = () => console.log('keydown');
  are.onkeyup = () => console.log('keyup');
</script>

テキストフィールドの中で適当な文字を入力してみましょう。ここではaを入力します。

keyboard-event_1

すると、keydownkeyupの順で出力されます。

このように、キーを押す作業とキーを離す作業によって文字の入力が行われることが分かります。

キー情報

キーボードイベントが発生しハンドラが実行されると、引数としてKeyboardEventオブジェクトが渡されます。
KeyboardEventオブジェクトは、イベント発生時に押されたキーの情報を持っています。

codeとkeyプロパティ

以下のプロパティにアクセスすると、キー情報を文字列で取得します。

  • code:押されたキーを取得
  • key:押されたキーを表す文字を取得

codeプロパティは実際に押された物理的なキーコードを取得する一方、keyプロパティは押されたキーを表す文字を取得します。

例えば、aが押されたパターンとShift + aが押されたパターンでは、KeyboardEvent.keyでは異なる文字を取得します。

<p>Press keys</p>
<textarea id="area"></textarea>

<script>
  let area = document.getElementById('area');
  area.onkeydown = (e) => {
    console.log('key: ' + e.key);
  };
</script>

aを押した場合:

keyboard-event_2

Shift + aを押した場合:

keyboard-event_3

一方、KeyboardEvent.codeはどちらのパターンも同じ結果です。

<p>Press keys</p>
<textarea id="area"></textarea>

<script>
  let area = document.getElementById('area');
  area.onkeydown = (e) => {
    console.log('code: ' + e.code);
  };
</script>

aを押した場合:

keyboard-event_4

Shift + aを押した場合:

keyboard-event_5

このように、KeyboardEvent.keyは文字であるため、Shift + aを押すことで入力したキーが大文字のAであると判断します。
KeyboardEvent.codeの場合、Shiftが押されているかどうかは関係なく、物理的に押されたキーコード、つまりKeyAを取得します。

押されたキー key code
a a KeyA
Shift + a A KeyA

キーコード

KeyboardEvent.codeで取得したKeyAのように、すべてのキーはキーコードを持っています。

キーボード上の位置やキーの種類に応じてコードが異なります。

キーの種類 キーコード
文字キー Key<letter> KeyA, KeyZ
数字キー Digit<number> Digit1, Digit9
特殊キー キーの名前 ShiftLeft,Tab

Shiftキーのように、キーボードの左右に二箇所配置されているキーの場合、キーの名前に加えてLeftまたはRightが示されます。

また、文字キーを表すキーコードは、key<letter>ではなくKey<letter>のように、最初の文字が大文字となるため注意が必要です。
押されたキーコードによって条件分岐を行いたい場合には、e.code == "Key<letter>"となります。

文字以外のキー

キーが文字ではなく特殊キーの場合、KeyboardEvent.keyはどのような値を取得するでしょうか。
このような場合、keyプロパティとcodeプロパティは類似しています。

押されたキー key code
Tab Tab Tab
Enter Enter Enter
Shift Shift ShiftLeft

実際にTab, Enter, Shiftキーを押したパターンをブラウザで検証してみます。

<p>Press keys</p>
<textarea id="area"></textarea>

<script>
  let area = document.getElementById('area');
  area.onkeydown = (e) => {
    console.log('key: ' + e.key);
    console.log('code: ' + e.code);
  };
</script>

keyboard-event_6

上述の通り、keyプロパティは押されたキーを表す文字を取得します。つまり、キーの意味を表すため、特殊キーの名前を取得する場合がほとんどです。

しかし、codeプロパティは厳密なキーを取得します。
Shiftを押した場合、keyプロパティはキーの位置まで取得しない一方、codeプロパティは位置まで厳密に区別します。

修飾子キー

前回の記事、マウスイベントの座標とキーでも解説しましたが、イベント時にこれらのキーが押された場合trueが返ります。

  • altKey:Altキーが押された場合
  • ctrlKey:Controlキーが押された場合
  • shiftKey:Shiftキーが押された場合
  • metaKey:Metaキーが押された場合

キーボードイベント時に、ShiftキーやControlキーが一緒に押されているか確認したい時にこれらのプロパティを使うと便利です。

例えば、テキストフィールドにShift + zが押されたらメッセージを表示したいような場合です。

<p>Press Shift + z</p>
<textarea id="area"></textarea>
<p id="text"></p>

<script>
  function showMessage(e) {
    if (e.shiftKey && e.code == 'KeyZ') {
      let text = document.getElementById('text');
      text.innerHTML = 'You pressed <b>Shift + z!';
    }
  }

  let area = document.getElementById('area');
  area.addEventListener('keydown', showMessage);
</script>

keyboard-event_7

テキストフィールドにShift + zを押すと”You pressed Shift + z!”と表示されるのが確認できます。

まとめ

今回は、キーボードイベントについて解説しました。

// ポイント
* keydown:キーが押された時に発生するイベント
* keyup:押されていたキーが離された時に発生するイベント
* code:押されたキーを取得するプロパティ
* key:押されたキーを表す文字を取得するプロパティ

合わせて読みたいイベント詳細シリーズ

第1回:マウスイベント -ボタン操作
第2回:マウスイベント -カーソル移動
第3回:マウスイベント -座標とキー
第4回:キーボードイベント(当記事)
第5回:フォーカスイベント
第6回:データの更新
第7回:フォームの送信
第8回:ページのロードとアンロード