KeyboardEvent
オブジェクトとは、キーボードに対するユーザの動作を表すオブジェクトです。 入力を受けたキーは個々のイベントによって表され、動作の種類はイベントの種類(keydown
/ keypress
/ keyup
)によって表されます。
KeyboardEvent
とは、単にキーへの動作を表したオブジェクトにすぎません。テキストの入力を処理したい場合は、HTML5 の input
イベントを代わりに使用してください。例えば、タブレット PC といった手書きのシステムでユーザがテキスト入力を行う場合、キーに関係するイベントが発火することはありません。
コンストラクタ
KeyboardEvent()
KeyboardEvent
オブジェクトを生成します。
メソッド
このインターフェイスでは、親に相当する UIEvent
と Event
の両者からもメソッドを継承しています。
KeyboardEvent.getModifierState()
Boolean
を返し、そのイベントが発火した際に修飾キー(Alt / Shift / Ctrl / Meta)が押されていたかどうかを表します。KeyboardEvent.initKeyEvent()
KeyboardEvent
オブジェクトを初期化します。このメソッドを実装しているのは Gecko のみであり(他のブラウザではKeyboardEvent.initKeyboardEvent()
を実装しています)、今後このメソッドを使用するべきではありません。その代わり、KeyboardEvent()
コンストラクタを用いるのが標準かつモダンな方法です。KeyboardEvent.initKeyboardEvent()
KeyboardEvent
オブジェクトを初期化します。このメソッドは Gecko で実装されておらず(Gecko ではKeyboardEvent.initKeyEvent()
を実装しています)、今後このメソッドを使用するべきではありません。その代わり、KeyboardEvent()
コンストラクタを用いるのが標準かつモダンな方法です。
プロパティ
このインターフェイスでは、親に相当する UIEvent
と Event
の両者からもプロパティを継承しています。
KeyboardEvent.altKey
読取専用Boolean
を返し、そのキーイベントが発火した際に Alt (OS X の場合は Option または ⌥ )キーが押されていればtrue
を返します。KeyboardEvent.char
読取専用- そのキーに該当する文字を表した
DOMString
を返します。そのキーに該当する文字が印字可能なものであれば、その文字を含んだ空でない Unicode 文字列が返されます。逆に印字可能ではなかった場合、戻り値は空文字列となります。補足: そのキーが複数の文字を挿入するマクロの働きをする場合、(最初の 1 文字目だけではなく)文字列全体が戻り値となります。注意: このプロパティは DOM Level 3 Events で削除されており、サポートしているのは IE9+ と Microsoft Edge のみです。 KeyboardEvent.charCode
読取専用- そのキーに該当する Unicode reference 番号を
Number
で返します。ただし、このプロパティはkeypress
イベントでのみ用いられます。char
プロパティは複数の文字を含むキーについては、最初の 1 文字目にあたる Unicode 値がcharCode
プロパティで取得できます。Firefox 26 からは、印字可能な文字に対してコード値を返すようになっています。注意: このプロパティは廃止されたため、可能であればKeyboardEvent.key
を代わりに使用すべきです。 KeyboardEvent.code
読取専用- そのイベントが表すキーについて、キーのコード値を
DOMString
で返します。 KeyboardEvent.ctrlKey
読取専用Boolean
を返し、そのキーイベントが発火した際に Ctrl キーが押されていればtrue
を返します。KeyboardEvent.isComposing
読取専用Boolean
を返し、そのイベントがcompositionstart
とcompositionend
の間に発火したものであればtrue
を返します。KeyboardEvent.key
読取専用- そのイベントが表すキーについて、キーの値を
DOMString
で返します。 KeyboardEvent.keyCode
読取専用- 押されたキーの(修飾されていない)値を指し示す、システムと実装に依存した数値コードを
Number
で返します。注意: このプロパティは廃止されたため、可能であればKeyboardEvent.key
を代わりに使用すべきです。 KeyboardEvent.keyIdentifier
読取専用- このプロパティは非標準であり、
KeyboardEvent.key
へ移行するため廃止されました。なお、このプロパティは DOM Level 3 Events の古い仕様に含まれていました。 KeyboardEvent.keyLocation
読取専用- このプロパティは
KeyboardEvent.location
の非標準なエイリアスでしたが、すでに廃止されました。なお、このプロパティは DOM Level 3 Events の古い仕様に含まれていました。 KeyboardEvent.locale
読取専用DOMString
を返し、キーボードに設定されているロケールを表します。ブラウザかデバイスがキーボードのロケールを知らなかった場合、この戻り値は空文字列となることがあります。補足: このプロパティは入力データのロケールを表すことはありません。例えば、ユーザが使用するキーボードレイアウトと入力テキストとで言語が異なる場合があります。KeyboardEvent.location
読取専用Number
を返し、キーボードや他の入力デバイス上におけるキーの位置を表します。KeyboardEvent.metaKey
読取専用Boolean
を返し、そのキーイベントが発火した際に Meta キー(Mac キーボードは ⌘ Command キー、Windows キーボードは Windows キー ⊞ )が押されていればtrue
を返します。KeyboardEvent.repeat
読取専用Boolean
を返し、そのキーが自動的に繰り返し押下されていた場合にtrue
を返します。KeyboardEvent.shiftKey
読取専用Boolean
を返し、そのキーイベントが発火した際に Shift キーが押されていればtrue
を返します。KeyboardEvent.which
読取専用- 押されたキーの(修飾されていない)値を指し示す、システムと実装に依存した数値コードを
Number
で返します(通常はkeyCode
と同じ動作です)。注意: このプロパティは廃止されたため、可能であればKeyboardEvent.key
を代わりに使用すべきです。
補足
イベントには keydown
/ keypress
/ keyup
の 3 種類があります。Gecko ではほとんどのキーにおいて、以下のようにキーイベントが連続して発火します。
- そのキーが最初に押された時点で
keydown
イベントが発火します。 - そのキーが修飾キーでなかった場合、
keypress
イベントが発火します。 - ユーザがキーから指を離した時点で
keyup
イベントが発火します。
特殊なケース
Caps Lock や Num Lock、Scroll Lock といったキーは LED 表示も切り替わります。このようなキーについて、Windows と Linux では keydown
と keyup
イベントのみが発火します。
Linux の Firefox 12 以前では keypress
イベントも発火していました。
しかし Mac OS X のイベントモデルに関する制約から、Mac OS X の Caps Lock は keydown
イベントのみが発火します。(2007 年モデル以前の)ラップトップでは Num Lock もサポートされていましたが、今日の Mac OS X では外部キーボードにおいても Num Lock はサポートされていません。Num Lock キーがある古い MacBook 上では、Num Lock キーによってイベントは何も発火しません。また、F14 キーが接続されている外部キーボードであれば、Gecko は Scroll Lock をサポートしています。しかし、特定の古いバージョンの Firefox では、このキーによって keypress
イベントが発火します。この矛盾する挙動はバグとして登録されています(詳しくは バグ 602812 を参照してください)。
auto-repeat の処理
キーが押されたままになると auto-repeat が始まります。これによって以下のようにイベントが連続して発火します。
keydown
keypress
keydown
keypress
- <<ユーザがキーから指を離すまで繰り返し>>
keyup
この流れは DOM Level 3 仕様書に定義されているものです。しかし、これには以下のような注意点があります。
Ubuntu 9.4 などの GTK 環境における auto-repeat
GTK を用いた環境の中には、auto-repeat 時にネイティブの key-up イベントが発火するものがあります。このため、キーが連続して押されているのか auto-repeat なのかを Gecko 側から認識することはできません。そのようなプラットフォームでの auto-repeat 時では、以下のようにキーイベントが連続して発火します。
keydown
keypress
keyup
keydown
keypress
keyup
- <<ユーザがキーから指を離すまで繰り返し>>
keyup
こういった環境では残念ながら、auto-repeat なのか連続して押されているのかを web コンテンツ側から区別することはできません。
Gecko 5.0 以前における auto-repeat の処理
Gecko 5.0 (Firefox 5.0 / Thunderbird 5.0 / SeaMonkey 2.2) 以前では、プラットフォーム間でキーボードのイベントハンドリングに差異が生じていました。
- Windows
- auto-repeat の挙動に関して Gecko 4.0 とそれ以降で変化はありません。
- Mac
- 最初に keydown イベントが発火した後、keyup イベントが発火するまでは keypress イベントのみが発火します。断続的に kedown イベントが発火することはありません。
- Linux
- イベントの挙動はプラットフォームによって異なります。ネイティブのイベントモデルによって、Windows のような挙動を示したり、Mac のような挙動を示すものがあります。
補足: 手動でイベントを発火させても、関連するデフォルトのアクションは生じません。例えば、手動でキーイベントを発火させても、その文字がテキストとして入力されることはありません。このような UI イベントの挙動は、セキュリティを意識して設計されています。この設計により、ブラウザとやり取りするユーザアクションをスクリプトが模倣できないようにしています。
使用例
<!DOCTYPE html>
<html>
<head>
<script>
'use strict';
document.addEventListener('keydown', (event) => {
const keyName = event.key;
if (keyName === 'Control') {
// not alert when only Control key is pressed.
return;
}
if (event.ctrlKey) {
// event.key が 'Control' でなくとも(例えば 'a' が押された時など)、
// Ctrl キーが同時に押されていれば event.ctrlKey は true となります。
alert(`Combination of ctrlKey + ${keyName}`);
} else {
alert(`Key pressed ${keyName}`);
}
}, false);
document.addEventListener('keyup', (event) => {
const keyName = event.key;
// ユーザが Ctrl キーから指を離した時点で、キーはアクティブではなくなります。
// そのため event.ctrlKey は false が返ります。
if (keyName === 'Control') {
alert('Control key was released');
}
}, false);
</script>
</head>
<body>
</body>
</html>
仕様
仕様書 | 策定状況 | 備考 |
---|---|---|
Document Object Model (DOM) Level 3 Events Specification KeyboardEvent の定義 |
草案 | 初期定義 |
KeyboardEvent
インターフェイスの草案は数多く提案されてきました。まず最初は DOM Events Level 2 でしたが意見がまとまらず破棄され、続いて DOM Events Level 3 が提案されました。これにより、非標準な初期化メソッドが実装されてしまいました(Gecko では DOM Events Level 2 の初期に定義されていた KeyboardEvent.initKeyEvent()
が、他のブラウザでは DOM Events Level 3 の初期に定義されていた KeyboardEvent.initKeyboardEvent()
です)。しかし両者のメソッドは、モダンなコンストラクタである KeyboardEvent()
で置き換えられています。
ブラウザ実装状況
機能 | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari (WebKit) |
---|---|---|---|---|---|
基本サポート | (有) | (有) | (有) | (有) | (有) |
constructor | (有) | 31.0 (31.0) | 未サポート | (有) | ? |
.char |
未サポート | 未サポート | 9 | 未サポート | 未サポート |
.charCode |
(有) | (有) | (有) | (有) | (有) |
.isComposing |
未サポート | 31.0 (31.0) | 未サポート | 未サポート | 未サポート |
.keyCode |
(有) | (有) | (有) | (有) | (有) |
.locale |
未サポート | 未サポート | (有) | 未サポート | 未サポート |
.location |
(有) | 15.0 (15.0) | (有) | 未サポート | 未サポート |
.repeat |
(有) | 28.0 (28.0) | (有) | 未サポート | 未サポート |
.which |
(有) | (有) | (有) | (有) | (有) |
.initKeyboardEvent() |
(有)[1] | 未サポート[2] | 9.0[3] | ? | (有)[1] |
機能 | Android | Firefox Mobile (Gecko) | IE Phone | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|
基本サポート | ? | (有) | ? | ? | ? |
constructor | ? | 31.0 (31.0) | ? | ? | ? |
.char |
? | 未サポート | ? | ? | ? |
.charCode |
? | (有) | ? | ? | ? |
.isComposing |
未サポート | 31.0 (31.0) | 未サポート | 未サポート | 未サポート |
.keyCode |
? | (有) | ? | ? | ? |
.locale |
? | 未サポート | ? | ? | ? |
.location |
? | 15.0 (15.0) | ? | ? | ? |
.repeat |
? | 28.0 (28.0) | ? | ? | ? |
.which |
? | (有) | ? | ? | ? |
.initKeyboardEvent() |
? | 未サポート | ? | ? | ? |
[1] WebKit と Blink における initKeyboardEvent()
の引数は DOM Level 3 Events 仕様の定義と異なっています(メソッド: initKeyboardEvent(in DOMString typeArg, in boolean canBubbleArg, in boolean cancelableArg, in views::AbstractView viewArg, in DOMString keyIdentifierArg, in number locationArg, in boolean ctrlKeyArg, in boolean altKeyArg, in boolean shiftKeyArg, in boolean metaKeyArg, in boolean altGraphKeyArg))。
[2] web アプリケーションが完全に壊れてしまうため、Gecko は initKeyboardEvent()
サポートしません。詳しくは バグ 999645 を参照してください。
[3] IE における initKeyboardEvent()
の引数は DOM Level 3 Events 仕様の定義と異なっています。(メソッド: initKeyboardEvent(in DOMString typeArg, in boolean canBubbleArg, in boolean cancelableArg, in views::AbstractView viewArg, in DOMString keyArg, in number locationArg, in DOMString modifierListArg, in boolean repeatArt, in DOMString locationArg)
)。詳しくは initKeyboardEvent()
に関する MSDN のドキュメント を参照してください。