コムセント 技術情報

  1. TOP
  2. コムセント 技術情報
  3. JavaScript でキーボード入力を取得する 2025

JavaScript でキーボード入力を取得する 2025

JavaScript では様々なイベントに対してリスナーを登録することができますが、一般的な Web サイト・システムを開発する際にキーボード入力に対してリアクションを取ることはよくあります。

そのほとんどは inputtextarea に対する change, input イベントを利用することでしょう。直接なんのキーが入力されたかを取得するのではなく、あくまでユーザが入力した結果を取得することが一般的です。

しかし、時にはキーボード入力そのものに対してリアクションを取ることが必要になることもあります。その場合は keydown, keyup, keypress イベントを利用しますが、これらからは KeyboardEvent オブジェクトを取得することができます。

かつてはこの KeyboardEvent のプロパティである keyCode を用いてキーコードを取得し、その数値によって何のキーが押されたか判定することが一般的でした。

この前僕はある Web システムでキーボードショートカットを実装することになったので、改めて JavaScript でキーボード入力を取得する方法を調べてみました。

すると、今では keyCode は非推奨となっており、代わりのプロパティが用意されていました。今回はそれらプロパティを解説したいと思います。

テスト環境

以下のような HTML ファイルを用意してテストしてみました。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>KeyboardEvent properties</title>
  <style>
    dl {
      display: flex;
      flex-wrap: wrap;
      justify-content: flex-start;
      margin: 0;
      padding: 0;
    }
    div {
      flex: 0 1 25%;
      margin: 0;
      padding: 0;
      display: flex;
    }
    dt {
      font-weight: bold;
      width: 150px;
    }
    dd {
      margin: 0;
      padding: 0;
    }
  </style>
</head>
<body>
<h1>KeyboardEvent properties</h1>
<section>
  <h2>keydown</h2>
  <dl>
    <div>
      <dt>.code</dt>
      <dd id="event-down-code">----</dd>
    </div>
    <div>
      <dt>.key</dt>
      <dd id="event-down-key">----</dd>
    </div>
    <div>
      <dt>.keyCode</dt>
      <dd id="event-down-key-code">----</dd>
    </div>
  </dl>
  <dl>
    <div>
      <dt>.ctrlKey</dt>
      <dd id="event-down-ctrl-key">----</dd>
    </div>
    <div>
      <dt>.metaKey</dt>
      <dd id="event-down-meta-key">----</dd>
    </div>
    <div>
      <dt>.shiftKey</dt>
      <dd id="event-down-shift-key">----</dd>
    </div>
    <div>
      <dt>.altKey</dt>
      <dd id="event-down-alt-key">----</dd>
    </div>
  </dl>
  <dl>
    <div>
      <dt>.isComposing</dt>
      <dd id="event-down-is-complete">----</dd>
    </div>
    <div>
      <dt>.repeat</dt>
      <dd id="event-down-repeat">----</dd>
    </div>
    <div>
      <dt>.location</dt>
      <dd id="event-down-location">----</dd>
    </div>
  </dl>
</section>
<section>
  <h2>keyup</h2>
  <dl>
    <div>
      <dt>.code</dt>
      <dd id="event-up-code">----</dd>
    </div>
    <div>
      <dt>.key</dt>
      <dd id="event-up-key">----</dd>
    </div>
    <div>
      <dt>.keyCode</dt>
      <dd id="event-up-key-code">----</dd>
    </div>
  </dl>
  <dl>
    <div>
      <dt>.ctrlKey</dt>
      <dd id="event-up-ctrl-key">----</dd>
    </div>
    <div>
      <dt>.metaKey</dt>
      <dd id="event-up-meta-key">----</dd>
    </div>
    <div>
      <dt>.shiftKey</dt>
      <dd id="event-up-shift-key">----</dd>
    </div>
    <div>
      <dt>.altKey</dt>
      <dd id="event-up-alt-key">----</dd>
    </div>
  </dl>
  <dl>
    <div>
      <dt>.isComposing</dt>
      <dd id="event-up-is-complete">----</dd>
    </div>
    <div>
      <dt>.repeat</dt>
      <dd id="event-up-repeat">----</dd>
    </div>
    <div>
      <dt>.location</dt>
      <dd id="event-up-location">----</dd>
    </div>
  </dl>
</section>
<div><textarea id="target-form"></textarea></div>
<script defer>
  document.getElementById('target-form').addEventListener('keydown', function(event) {
    document.getElementById('event-down-code').textContent = event.code;
    document.getElementById('event-down-key').textContent = event.key;
    document.getElementById('event-down-key-code').textContent = event.keyCode;
    document.getElementById('event-down-ctrl-key').textContent = event.ctrlKey;
    document.getElementById('event-down-meta-key').textContent = event.metaKey;
    document.getElementById('event-down-shift-key').textContent = event.shiftKey;
    document.getElementById('event-down-alt-key').textContent = event.altKey;
    document.getElementById('event-down-is-complete').textContent = event.isComposing;
    document.getElementById('event-down-repeat').textContent = event.repeat;
    document.getElementById('event-down-location').textContent = event.location;
  });
  document.getElementById('target-form').addEventListener('keyup', function(event) {
    document.getElementById('event-up-code').textContent = event.code;
    document.getElementById('event-up-key').textContent = event.key;
    document.getElementById('event-up-key-code').textContent = event.keyCode;
    document.getElementById('event-up-ctrl-key').textContent = event.ctrlKey;
    document.getElementById('event-up-meta-key').textContent = event.metaKey;
    document.getElementById('event-up-shift-key').textContent = event.shiftKey;
    document.getElementById('event-up-alt-key').textContent = event.altKey;
    document.getElementById('event-up-is-complete').textContent = event.isComposing;
    document.getElementById('event-up-repeat').textContent = event.repeat;
    document.getElementById('event-up-location').textContent = event.location;
  });
</script>
</body>
</html>

テキストエリアにフォーカスを当てた状態でキーボード入力を行うと、様々な情報が表示されます。

下記にも機能は同じものを用意してみました。

keydown

.code
----
.key
----
.keyCode
----
.ctrlKey
----
.metaKey
----
.shiftKey
----
.altKey
----
.isComposing
----
.repeat
----
.location
----

keyup

.code
----
.key
----
.keyCode
----
.ctrlKey
----
.metaKey
----
.shiftKey
----
.altKey
----
.isComposing
----
.repeat
----
.location
----

入力されたキーを得る

KeyboardEvent - Web API | MDN で参照できるように、KeyboardEvent オブジェクトには様々なプロパティが用意されています。

かつて主流であった keyCode は非推奨となり、代わりに code, key, などが用意されています。

この codekey が入力されたキーを取得するためのプロパティです。

keyCode は数値でキーコードを表していましたが、これらは人間にも分かりやすい文字列で表現されています。

ではなぜ二つも用意されているのかというと、code は物理的なキーの位置を表し、key は押されたキーの実際の文字を表すためです。

code

一般的には key を利用することが多いのですが、それは code が入力されたキーの情報ではなく、物理的なキーの位置を表すためです。どういう意味でしょうか?

MDN では以下のような警告がされています。

警告: これはユーザーのキーボードレイアウトを無視します。つまり、ユーザーが QWERTY キーボードレイアウトの "Y" の位置(ホーム行の上の行の中央付近)でキーを押した場合、ユーザーが QWERTZ キーボード(これはユーザーが "Z" を期待し、他のすべてのプロパティが "Z" を示すことになる)または Dvorak キーボードレイアウト(これはユーザーが "F" を期待する)であっても、常に "KeyY" を返します。ユーザーに正しいキーストロークを表示したい場合は、 Keyboard.getLayoutMap() を使用してください。

例えばドイツなどの国で一般的に使用されてキーボードでは YZ の位置が逆になっています。ドイツ語では Z を多用するのに対し、Y はさほど使用しないという理由から、このようなキーボード配列は QWERTZ と呼ばれています。

引用元: KeyboardEvent - Web API | MDN

このようなキーボードを使用した場合、一番左下にあるアルファベットキーを押した際の codeKeyZ となります。これは code が物理的なキーの位置を表すため、たとえY のキーであっても一般的な QWERTY 配列のキーボードにおける Z の位置にあるため、 KeyZ となるためです。

key

対して、key は押されたキーの実際の文字を表します。つまり、Y と刻印されているキーを押した場合は、それが刻印間違いでも無い限り y となるでしょう。

ただし、key は押されたキーが何であるかではなく、あくまで何が入力されたかを表します。

例えば、Shift キーを押しながら 1 キーを押した場合、key! となります。同じく、 CapsLock 状態で a キーを押した場合、keyA となります。

特殊なキーと同時押しされているか調べる

keycodekeydown, keyup イベントで取得することで、どのキーが押されたかを取得することができます。この二つのイベントを利用することで、長押しや同時押しを検知することも可能です。

しかし、実は KeyboardEvent オブジェクトには同時押しによく使用される特殊なキーを判定するためのプロパティが用意されています。

shiftKey

あるキーが押された際、「Shift」キーが押されているかどうかを判定するためのプロパティです。true または false が返されます。

例えば、 event.key.toLowerCase() === 'a'' である際に event.shiftKeytrue であれば、「Shift」キーと同時に「A」キーが押されたことがわかります。

この shiftKey は Windows であっても macOS であっても同じ「Shift」キーを表しますが、これ以降の同タイプのプロパティはそれぞれの OS で違います。

altKey

上記 shiftKey の「Alt」キーバージョンです。

このプロパティは Windows では文字通り「Alt」キーを対象とするのですが、、macOS では「Option」キーが該当します。キーの用途や位置としては似ていると思いますが、 macOS をメインで使用している開発者は戸惑うプロパティ名かもしれません。

ctrlKey

上記 shiftKey の「Ctrl」キーバージョンです。

このプロパティは altKey よりさらに混乱しやすく、 Windows では「Ctrl」キーを対象とするのですが、 macOS では「Control」キーが該当します。

Windows では 「C」キーと組み合わせてコピー、「Z」キーと組み合わせて Undo 操作など、多くのショートカットで使用するキーですが、 macOS で同様の用途に使用するキーは「Control」キーではなく「Command」キーです。

なので、 Windows, macOS 両方で同じショートカットを使用する場合、 ctrlKey と次の metaKey の両方をチェックする必要があります。

metaKey

上記 shiftKey の「Windows」&「Command」キーバージョンです。

このプロパティは Windows では「Windows」キーを対象とするのですが、 macOS では「Command」キーが該当します。

macOS では Windows 版の「Ctrl」キーの代わりに「Command」キーを使用するため、このプロパティは macOS でのショートカットを判定する際に多用することになるでしょう。

反面、 Window では「Windows」キーを検出するのですが、ブラウザによっては「Windows」キーを検出することができないことがあるため、注意が必要です。

KeyboardEvent.metaKey は読み取り専用のプロパティで、 プロパティは、イベントが発生したときに Meta キーが押されていたか (true) あるいは押されていなかった (false) かを示す論理値を返します。オペレーティングシステムによっては、キーが検出されないように遮蔽されることがあります。

警告: 少なくとも Firefox 48 の時点で、 ⊞ Windows キーは "Meta" キーとみなされなくなりました。⊞ Windows キーが押されたとき KeyboardEvent.metaKey は false になります。

変換状態にあるか判定する - isComposing

isComposing プロパティは、IME の変換状態にあるかどうかを判定するためのプロパティです。

このプロパティが true の場合、IME が変換中であることを示し、false の場合は変換中でないことを示します。

このプロパティを利用することで、キーボード入力は発生しているものの、その入力が確定されていない場合に対してリアクションを取ることができます。

キーの繰り返し入力を判定する - repeat

repeat プロパティは、キーが長押しされているかどうかを判定するためのプロパティです。

このプロパティが true の場合、キーが長押しされていることを示し、false の場合は長押しされていないことを示します。

長押し状態になると、通常入力欄では同じ文字が繰り返し入力されますが、このプロパティを利用することで、長押し状態に対してリアクションを取ることができます。実際は文字を入力しないキー、例えば Shift キーや Backspace キーなども検出することができます。

キーの位置を取得する - location

location プロパティは、キーがどの位置にあるかを示すためのプロパティです。より具体的には、一つのキーボードに同じボタンが二つ以上あるキーの相対的な位置、例えば左右の Shift キーなどを判定するためのプロパティです。

このプロパティは数値で返され、以下の値が用意されています。

  • 0: 汎用のキー。例えば A キーや 1 キーなど。
  • 1: 左側のキー。例えば Shift キーや Ctrl キーなど。
  • 2: 右側のキー。例えば Shift キーや Ctrl キーなど。
  • 3: テンキーのキー。

このプロパティを利用することで、左右どちらの Shift キーが押されたかどうかを判定することができます。

まとめ

keyCode 一本でキーコードを取得していた時代から、code, key などのプロパティが用意され、キーボード入力を取得する方法が進化しています。

新しいプロパティを使用する際は Can I use などを使用して、対応ブラウザを確認することをお勧めしますが、一般的な使用方法であれば上記で紹介したプロパティのほとんどは安心して使用できるでしょう。

とても複雑な機能を実装するのであればライブラリやパッケージの取得が視野に入ってくると思いますが、簡単な処理であればバニラ JavaScript で実装することも容易です。

プログラマー/N.Go

このメンバーの記事一覧へ

おすすめ記事