ふだんなんとなく使っているけれど詳しいことは知らない,そんなものの代表格であるこいつらについて,一度きちんと勉強しなくてはならないと薄々考えていたので補習することにした. 学習のまとめがこの文書である.
CAVEAT: 以下の内容は基本的な挙動であり,ブラウザによって挙動が変化することがある.これは公式ドキュメントではなく,誤記が含まれているおそれがあり,その他いかなる内容も保証しない.
keydown,keypressed,keyup
これらは全てイベント(KeyboardEvent
)である.
overview
attribute: char
,key
いずれのイベントでもchar
(string
)そしてkey
(string
)を読むことができる.
押下されたキーが印字可能な文字に対応するとき,char
はその文字を含むunicode文字列であり,key
もこれと等しい文字列である.キーに印字表現がないときは,char
は空文字列であり,キーを表現する文字列が定義されているときはkey
はその文字列であり,さもなくばkey
は"Unidentified"
である.key
がとりうる値はMDNのドキュメントで確認できる.
char
とkey
はいずれもreadonlyである.
deprecated attribute: charCode
,keyCode
いずれのイベントでもcharCode
,keyCode
を読むことができるが,これらはdeprecatedになっており,可能な限りchar
かkey
を使わなければならない.複数文字を入力するマクロとしてキーが使われた場合,char
は最初の1文字ではなく入力文字列全てになる.
modifiers
いずれのイベントでも,ctrlKey
,shiftKey
,altKey
,metaKey
(いずれもboolean
)を読むことで,イベント発火時に押下されていた修飾キーを識別できる.
auto-repeat
オートリピート時には,基本的にkeydown
,keypress
が繰り返し発火され,キーを離したタイミングでkeyup
が発火する.ただし環境によってはkeydown
, keypress
,keyup
が繰り返し発火される(実際に連打しているように見える)ため注意する.
keydown
キーが押し込まれたときに発火する.
keypress
キーが押し込まれ,そのキーが文字を生成するときに限って発火する.DOM L3仕様により順序はkeydown
の後である.
DOM L3でdeprecatedになっており,代替として(よりアクセシビリティの面でも優れる)HTML5 input
を使うことが推奨される.
Chromeは,一定のショートカットにおいてこのイベントを発火しない.ショートカットを実装したい場合はkeydown
を使う.
keyup
キーが離されたときに発火する.
input
<input>
または<select>
,<textarea>
の値(value
属性)が変化したときに発火する.つまり,直接変化させた場合でなくとも発火するので,入力支援のために使用するときは注意して扱うべき*1イベントである.さらに(名称からすると非直感的ではあるが)<input>
のうちtype=checkbox
またはtype=radio
はユーザがクリックしたときvalue
属性が変化しないため,このイベントを発火しない.
キーボードではない手段(音声入力など)によって値が変化したときにも発火するため,アクセシビリティの面で優れている.
InputEvent
を継承しているため,data
属性を通じて挿入された文字列を取り出すことができる.また,文字列の挿入を伴わない変化(文字の削除など)によって発生したイベントによるものであるときは,data
は空文字列である.
したがって,このイベントはあらゆるキーの検出には向かない.
またInputEvent
にはisComposing
属性があり,音声認識中や漢字変換を行っているかどうかを判別することができる.
まとめ
charCode
,keyCode
は新規プロダクトでは避け,char
またはkey
を使わなければならない.- アクセシビリティ確保の観点から,
keypress
よりもinput
を積極的に使いたい. - 単純なショートカットの実装には
keydown
を使うべきである.- submitショートカットとして使う場合は
keyup
を使い,変換完了を待つ必要がある.
- submitショートカットとして使う場合は
- ラジオボタンとチェックボックスについては,
input
ではなくchange
を使わなければならない. - 入力支援のために
input
を使うときは,入力検知が際限なくループするのを防ぐために適切な状態管理が必要である.
参考文献
https://www.w3.org/TR/DOM-Level-3-Events/#keys
*1:つまり変化が変化を発生させうるため,停止しない状態を作り出せてしまうことに留意すべき