非推奨
- keypress event
https://developer.mozilla.org/en-US/docs/Web/API/Document/keypress_event - KeyboardEvent.keyCode
https://developer.mozilla.org/ja/docs/Web/API/KeyboardEvent/keyCode
使うべきもの
- beforeinput, keydown, keyup
- KeyboardEvent.code (IEは❎)
- KeyboardEvent.key
code
https://developer.mozilla.org/ja/docs/Web/API/KeyboardEvent/code
このプロパティは、キーに関連付けられている文字ではなく、入力デバイス上の物理的な位置に基づいてキー入力を扱いたいときに役立ちます。
KeyboardEvent.code で報告された値を用いてキー入力で生成される文字を判断するべきではありません。キーコード名がキー上に印刷されている実際の文字や、キーが押されたときにコンピューターが生成する文字と一致するとは限らないからです。
キーイベントに対応する文字が何であるかを判別するには、、代わりにKeyboardEvent.key プロパティを使用してください。
key
https://developer.mozilla.org/ja/docs/Web/API/KeyboardEvent/key
押されたキーが印刷表現を持っている場合は、返された値は空ではない Unicode 文字の文字列で、キーの印刷表現が入ります。
code/keyの比較記事
https://ryjkmr.com/keyboardevent-keycode-to-keyboardevent-code/
変換時のEnterを除外したい
ここまで読んで、Enterを押したらタグが追加されるように書いてみる
const handleEnter = (e: React.KeyboardEvent<HTMLInputElement>): void => {
if (e.key !== 'Enter') {
return
}
const newTag: TTag = {
id: Date.now(),
name: value,
color: 'tagDefault',
}
setTagList(prev => {
return [newTag, ...prev]
})
onEnter(newTag)
}
これだとIMEで漢字に変換した時のEnterでも発火されてしまう。
MDNに書いてあった対処法
eventTarget.addEventListener("keydown", event => {
if (event.isComposing || event.keyCode === 229) {
return;
}
// do something
});
上記を真似してisComposingを追加。
if (e.key !== 'Enter' || e.isComposing) {
return
}
エラーでる。えーー。。なんで。。。。
Property 'isComposing' does not exist on type 'KeyboardEvent<HTMLInputElement>'.
https://twitter.com/saitolume/status/1348494840594513923
▲TypeScriptの問題みたい。TSまだまだ苦手なのでここでは戦えない><
代わりに compositionstart と compositionend で 変換中かを監視するようにしてみる。
(参考記事 https://blog.utgw.net/entry/2021/06/29/212256)
Reactだと onCompositionStart と onCompositionEnd が使える。
https://ja.reactjs.org/docs/events.html#composition-events
const [composing, setComposing] = useState(false)
const handleEnter = (e: React.KeyboardEvent<HTMLInputElement>): void => {
if (e.key !== 'Enter' || composing) {
return
}
〜略〜
}
<SInput
type="text"
id={id}
name={name}
value={value}
onChange={e => onChange(e)}
autoComplete={autoComplete}
onCompositionStart={() => setComposing(true)}
onCompositionEnd={() => setComposing(false)}
onKeyDown={e => handleEnter(e)}
/>
上手くいったっぽい!!👏
明日、他のブラウザでも確認してみよう。