🐣 Enterキーでイベント発火
作成日: 2022/02/05
3

非推奨

使うべきもの

  • 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に書いてあった対処法

https://developer.mozilla.org/en-US/docs/Web/API/Document/keydown_event#ignoring_keydown_during_ime_composition

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)}
        />

上手くいったっぽい!!👏
明日、他のブラウザでも確認してみよう。


制作会社でフロントのコーディングやWordpressのテーマ開発をしてます。 本命はJavascriptです😋 目指せフロントエンドエンジニア👊