変換中のEnterで誤送信|isComposingとSafariの罠

日本語を打っていて、変換を確定しようとEnterを押しただけなのに、書きかけのメッセージが送信されてしまった。そんな経験はありませんか。

自分が作ったチャット画面や入力フォームで同じことが起きると、それはバグ報告として返ってきます。やっかいなのは、英語環境ではまず再現しない点です。手元で試しても起きず、原因がなかなか見つかりません。

この記事では、この誤送信が起きる仕組みと、正しい直し方を説明します。結論を先に言うと、対策はキー入力のイベントに含まれるisComposingを見ることです。そしてSafari向けに、keyCodeが229かどうかも併せて見ます。

目次

IME変換中のEnterが「送信」と誤解される仕組み

変換を確定するEnterと、送信するEnterは、プログラムから見ると同じキー入力です。ここが誤送信の出発点になります。

日本語の入力にはIMEを使います。IMEはInput Method Editorの略で、かな入力を漢字に変換してくれる仕組みのことです。IMEを通した入力は、文字が確定するまで「組み立て中」の状態にあります。そしてこの組み立て中にも、キーを押したことを知らせるkeydownイベントは発生します。

身近な例で考えてみましょう。「ありがとうございます」と打ち、変換候補を選んでEnterで確定する。この一連の操作のなかで、Enterは最低でも1回、候補を選び直せばもっと多く押されます。画面側が「Enterが来たら送信する」とだけ書いていれば、確定した瞬間に文章が飛んでいきます。

英語で入力する人には、この変換という操作そのものがありません。だから海外製のサンプルコードは、この状況を考えずに書かれていることが多いのです。

IME変換中のEnterと確定後のEnterが同じkeydownとして届く流れと、isComposingで見分ける位置を示した図
図: IME変換中のEnterと確定後のEnterが同じkeydownとして届く流れと、isComposingで見分ける位置を示した図(筆者作成)

IME変換中のEnterはisComposingで見分ける

標準的な見分け方は、キーボードイベントが持つisComposingという値を確認することです。

isComposingは、文字の組み立てが始まったことを示すcompositionstartと、終わったことを示すcompositionendの間に発生したイベントで真になります。つまり変換確定のEnterなら真、確定後にあらためて押したEnterなら偽になる、という理屈です。

Google Chromeチームが公開している開発ガイダンスでも、textarea(複数行の入力欄)で独自にEnter送信を実装する場合は、送信前にisComposingを確認するよう示されています。書き方はごく短いものです。

  • keydownでEnterが押され、かつShiftが押されていないことを確認する
  • そのうえでisComposingが真なら、何もせずに処理を抜ける
  • 偽のときだけ送信の処理へ進む

順序が大切です。isComposingの確認を後回しにすると、確定のたびに送信が走ります。

SafariではisComposingが当てにならない

ところが、isComposingだけでは足りません。Safariでは確定Enterのときに、isComposingが偽になることがあります。

原因はWebKitに報告されていたバグ(#165004)です。本来ならkeydownを受け取ったあとにcompositionendが起きるはずのところ、Safariでは確定用のkeydownより先にcompositionendが発生していました。イベントを受け取った時点で組み立てはすでに終わったことになっており、isComposingは偽として届く、というわけです。

ただし、ここは調べた時点の状況を書き添えておきます。この順序の問題は別のバグ(#311717)として2026年4月にWebKit本体で修正され、仕様どおりの順序が既定で有効になりました。#165004も重複として解決済みです。つまり最新のSafariでは、この回避策はもう必要ない方向へ向かっています

そこで併用されるのが、keyCodeが229かどうかという判定です。229はWindowsの仮想キーコードVK_PROCESSKEYに由来する値で、「IMEが処理中のキー入力」を表すものとして長く使われてきました。isComposingが偽でも、この値なら確定Enterを拾えます。

keyCode自体は古い仕様で、非推奨とされています。それでも、更新されていないSafariを使っている人は当分いなくなりません。標準の判定であるisComposingを主に置き、229の判定は古い環境のための保険として足す。この組み合わせが、いまのところ現実解です。数年後にはisComposingだけで足りるようになる、という前提で書いておくと、後から読む人が消す判断をしやすくなります。

そもそも独自のEnter送信を作らないのが最も安全

ここまで対策を並べましたが、いちばん確実なのは自分でEnterを扱わないことです。

理由は単純で、1行のinput要素とform要素、そして送信ボタンを素直に使えば、Enterでの送信はブラウザ側がやってくれるからです。これを暗黙的送信と呼びます。IMEの状態を考慮するのはブラウザの仕事になるため、こちらでcompositionイベントを管理する必要がありません。

独自の判定が必要になるのは、限られた場面だけです。たとえばチャット画面でよくある「Enterで送信、Shift+Enterで改行」のように、textareaに独自の操作を割り当てる場合です。逆に言えば、それ以外の検索欄やログインフォームで自前のkeydown送信を書いているなら、いったん外せないかを疑ったほうが早く直ります。

「英語環境では再現しない」不具合の型を覚えておく

この誤送信は、単発の知識としてより「型」として覚えておく価値があります。

海外製のライブラリやAIが出力したサンプルコードは、英語入力を前提にしていることがあります。そのまま取り込むと、日本語環境でだけ壊れます。しかもこの種の不具合は、例外も発生せずログにも残りません。「たまに勝手に送信される」という曖昧な報告だけが上がってきます。ログを見ても原因がわからない種類の問題と同じで、当たりをつける知識がないと調査は長引きます。

同じ型に当てはまる例は、ほかにもあります。

  • 全角スペースや全角数字が入力に混ざり、検証をすり抜ける
  • 濁点の表現が2通りあり、同じに見える文字列が一致しない
  • 日付や氏名の並び順が、英語圏の前提のままになっている

入社1〜3年目のうちにこの型を持っておくと、原因の見当をつける速さが変わります。そして気づいた前提は、コードのコメントだけでなく設計の意図を残す文書に一行でも書いておくと、次の担当者が同じ回り道をしません。

まとめ:IMEを考えたEnter送信の要点

  • 変換確定のEnterと送信のEnterは同じキー入力なので、区別しないと誤送信になる
  • 標準の判定はisComposing。古いSafariでは偽になるため、keyCodeが229かの判定を保険として併用する(順序の不具合はWebKit本体では2026年4月に修正済み)
  • textareaでの独自操作が必要な場面以外は、formの暗黙的送信に任せるのが安全

まずは自分が関わっている画面で、keydownからそのまま送信している箇所がないかを探してみてください。

参考リンク

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

目次