JavaScriptで漢字変換中のInputイベントの話

JavaScriptのInputにおいて漢字変換途中の発生イベントの話です

はじめに

今回、入力エレメントに文字を入力すると裏でAPIサーバと通信してシステム内の候補を出す… ってよくある機能を実装しようと思っておりました。

すると… 文字が未確定状態で送信されるので無駄パケットが発生していました。

調査するとinputエレメントのイベントの動きが特殊だったのでそれをまとめておきたいと思います

原因

さて、今回は KeyDownで実装していましたが、onChangeでも動作を見たいと思います。

未確定文字列っとなるのはどういった場合でしょうか?

入力エレメントで「りんごj」と送信した場合の例を挙げたいと思います

「r」「り」「りん」「りんg」「りんご」と漢字変換途中の英字でも発火します。
今回はこの抑制方法をまとめておきます

はじめに漢字変換中の入力を制限すれば良いので漢字変換中を判断するフラグを調べました…

event.nativeEvent.isComposing が該当なようです

https://developer.mozilla.org/ja/docs/Web/API/KeyboardEvent/isComposing

ではでは実際に イベントを確認します

onChangeonKeyEvent
Key入力valueisComposingkeyCodeisComposing
rrtrue229false
itrue229true
nりんtrue229true
gりんgtrue229true
oりんごtrue229true
jりんごjtrue229true
[Enter]229true

重要なポイントをまとめます

  • KeyDownの一つ目のisComposingはfalseです

はい、漢字変換の一文字目がisComposingがfalseってのは結構めんどくさかったです。

だったらどうするか?keyCodeにて判断します

それで実装するが…

このkeyCodeはすでに非推奨なのですよね

https://developer.mozilla.org/ja/docs/Web/API/KeyboardEvent/keyCode

はい実際に実装した例を挙げます


const IMEInput = () => {
    const handleKeyDown = (event: any) => {
        // @ts-ignore 非推奨は理解しているがIMEの編集中であるかの判断のために使用
        const keyCode = event.keyCode;
        // isComposingはIME入力中かどうかを判定する、ただし頭の文字列はfalse IME入力中の場合は229が返ってくる
        if (event.nativeEvent.isComposing || keyCode === 229) {
            return
        }
        console.log("Server access...")
    }
    return <input onKeyDown={handleKeyDown} />
}

export default IMEInput

これで無駄なサーバアクセスがない状態で実装できました

終いに

今回はシンプルにJavaScriptの漢字変換中のイベントを書いてみました