React の onKeyDown
/ onKeyPress
/ onKeyUp
/ onChange
の挙動が、クロスブラウザでどのように変わるのかを調査しました。
調査方法・内容
- それらのイベントに
event.key
/event.keyCode
/event.target.value
の値を記録するハンドラを設定し、ひとつの<input type="text"/>
に全イベントを付与する。 - 下記の「キーボードの操作」をクロスOS/ブラウザ環境で行って、その履歴を保存する。
具体的には、CodePen に書いた簡単な自作ツール で行いました。
環境について
- 使用したハードウェアは、日本語キーボードの Mac Book Pro です。
- Win 仮想環境は VirtualBox で構築しており、また(参考記事が見つかりませんが) Mac のキーボードと連動する設定をした上で行っています。
キーボードの操作
- 「かな」を押す
- 「A」を押す
- 「K」を押す
- 「A」を押す
- 「スペース」を一度押して「赤」に変換する
- 「Enter」を押して変換を確定する
Mac/Chrome
Event name | key | keyCode | target.value |
---|---|---|---|
onKeyDown | a | 229 | |
onChange | あ | ||
onKeyUp | a | 65 | あ |
onKeyDown | k | 229 | あ |
onChange | あk | ||
onKeyUp | k | 75 | あk |
onKeyDown | a | 229 | あk |
onChange | あか | ||
onKeyUp | a | 65 | あか |
onKeyDown | 229 | あか | |
onChange | 赤 | ||
onKeyUp | 32 | 赤 | |
onKeyDown | Enter | 229 | 赤 |
onChange | 赤 | ||
onKeyUp | Enter | 13 | 赤 |
Mac/Safari
Event name | key | keyCode | target.value |
---|---|---|---|
onKeyUp | Unidentified | 0 | |
onChange | あ | ||
onKeyDown | Unidentified | 229 | あ |
onKeyUp | Unidentified | 65 | あ |
onChange | あk | ||
onKeyDown | Unidentified | 229 | あk |
onKeyUp | Unidentified | 75 | あk |
onChange | あか | ||
onKeyDown | Unidentified | 229 | あか |
onKeyUp | Unidentified | 65 | あか |
onChange | 赤 | ||
onKeyDown | Unidentified | 229 | 赤 |
onKeyUp | 32 | 赤 | |
onChange | 赤 | ||
onKeyDown | Unidentified | 229 | 赤 |
onKeyUp | Enter | 13 | 赤 |
- 最初の keyCode=0 の onKeyUp は、「かな」に対応しています。
-
点については、facebook/react の以下の Issue が参考になります。event.key
がUnidentified
である- SyntheticEvent.key property is "unidentified" in Safari on Mac OS X
- 2017/08/01 に Mac OS X/Safari で確認したところ、正常に取得できていました
- なお、
event.key
が返す文字列の一覧は getEventKey.js にあります。
Mac/Firefox
Event name | key | keyCode | target.value |
---|---|---|---|
onKeyUp | KanjiMode | 21 | |
onKeyDown | a | 65 | |
onChange | あ | ||
onChange | あk | ||
onChange | あか | ||
onChange | 赤 | ||
onChange | 赤 | ||
onKeyUp | Enter | 13 | 赤 |
- 大分少ないです。これは変換中のキー操作が一律フックできないためです。
仮想 Win8.1/IE11
Event name | key | keyCode | target.value |
---|---|---|---|
onKeyUp | Unidentified | 243 | |
onKeyDown | a | 229 | |
onChange | あ | ||
onKeyDown | k | 229 | あ |
onChange | あk | ||
onKeyDown | a | 229 | あk |
onChange | あか | ||
onKeyDown | 229 | あか | |
onChange | 赤 | ||
onKeyDown | Enter | 229 | 赤 |
onKeyUp | Enter | 13 | 赤 |
onKeyUp | Enter | 13 | 赤 |
- 変換確定時の onKeyUp で Enter が 2 回飛んでいます。
- これは仮想環境であるが故なのだろうか・・・?
番外: document.querySelector('input').value = "a"
全環境で、onChange
は反応しませんでした。
まとめ
頑張りたくない人は onChange
だけで過ごした方が良い。
その他の参考サイト
-
Markdown Tables Generator
- table タグをコピペして Markdown 形式に変換してくれるツール
折角なので、埋まってなかった React Advent Calendar 2016 の 12 日目を乗っ取ってみたんですが、意外と精神にくるのでやらなければ良かったと思ってます・・・。