[2024年4月25日 追記] Safariの動作について考慮漏れがありましたので、一部追記・編集しました。
新宿にオフィスのあるClassiは、岡山在住の私のような地方在住者だけでなく、いわゆる通勤圏内に在住していてもリモートワークで働いている人が多い会社です。必然的にミーティングはいわゆるオンラインミーティングとなり、主にGoogle Meetが利用されています。
そのGoogle Meetのチャット機能、ここ1週間ぐらい「IMEで日本語に変換のために押すエンターキーで送信されてしまう」という現象が発生しています。このエントリーを読まれている時点では対応しているかも知れませんが、2024年4月22日17時時点ではその現象は続いています(Windowsでは再現しないという情報もあります)。
エンターキーに頼らない日本語入力を頑張りましたが、手癖というのは抜けないものです
この現象は、Google Meetに限らずさまざまなウェブサービスで発生しています。ChatGPTも話題になってからしばらくはこのような挙動でした。日本や東アジア圏を中心に、IMEを利用しているユーザーからのフィードバックでいずれは対応されると待つのが基本ですが、普段の業務利用も絡んでいるので対応策を整理しました。
ここからは作成したデモに基づいて進めて行きます。
「入力欄」で日本語変換を行って確定のためにエンターキーを押すと上に反映される状態を再現しています。その後、「IME変換中の送信停止」と書かれたボタンを押すと、変換確定のエンターキーでは反映されなくなりますが、変換を行っていないときのエンターキーには反応します。
対応方法
基本的な対応の方針は以下です。
「イベントキャプチャでいち早くIME変換中のエンターキー入力を捕捉して伝播させないようにする」
それを実装したのが下記のコードです。
document.addEventListener('keydown', function(event) { if ((event.key === 'Enter' && event.isComposing) || event.keyCode === 229) { event.stopPropagation(); } },{capture: true});
「イベントキャプチャでいち早く」
addEventListener
の第3引数{capture: true}
がその実装です。このオプションでcaptureを有効にすると、keyDownイベントの伝播がターゲットから親方向のバブリングではなく、ドキュメントからターゲットに向かうキャプチャとなり、まずはdocumentがkeyDownの発火対象になります。
参考)
「IME変換中のエンターキー入力を捕捉」
(event.key === 'Enter' && event.isComposing) || event.keyCode === 229
の条件式がその判定です。
event.key === 'Enter'
はkeyDownされたキー名、event.isComposing
はIME変換中であればtrueになります。また、Safariの挙動への対応として非推奨プロパティですがevent.keyCode === 229
も加えています。keyCodeの229は、IMEに関連したkeyCodeとして定義されています。この条件に合った場合、日本語変換時のエンターキーと判断し、後述のevent.stopPropagation()
で子要素に対しての伝搬を中止します。
参考)
「伝播させないようにする」
event.stopPropagation()
がそのメソッド名の通り伝搬を止めます。documentの段階で伝播しないようにすることで、送信のイベントが用意されているinputフィールドにエンターキーの入力が伝わらないようになっています。
参考)
ここまでが「IME変換中のエンターキーで送信される」への対応の基本です。
どうやって稼働中のウェブサービスに適用するか?
対応方法のJavaScriptがあるとして例えばGoogle Meetで困っていた場合、どうすれば良いでしょうか?フィードバックを送ったり、オープンソースであればPullRequestを送ったりという対応が思い浮かびますが、「今すぐ」の解決策は手元のブラウザに上記のJavaScriptを適用することです。
DevToolsのコンソールで実行する
上記のコードをDevToolsのコンソール画面で実行すると、コードの内容が適用されます。該当のサービスにアクセスする度に実行する必要があります。
ブックマークレットを作成する
下記のコードは、この記事で紹介しているJavaScriptをブックマークレットで利用可能にしたものです。ブックマークとして登録しておくと、必要な時に呼び出せば以降は適用されています。こちらも該当のサービスにアクセスする度に実行する必要がありますが、ブックマークを呼び出すだけです。
javascript:(function()%20%7Bdocument.addEventListener('keydown'%2Cfunction(event)%7Bif((event.key%3D%3D%3D'Enter'%26%26event.isComposing)%7C%7Cevent.keyCode%3D%3D%3D229)%7Bevent.stopPropagation()%7D%7D%2C%7Bcapture%3A%20true%7D)%7D)()
このブックマークレットのコードは同僚の@koki_developが作成したBookmarklet.linkを利用して生成しました。
拡張機能を使う
上記のJavaScriptの作用を組み込んだ拡張機能を利用すれば、アクセスする度に行うといった面倒もなく適用できます。似たようなケースで、ChatGPT向けの「変換中のエンターキーで送信されるのを防ぐ」拡張を散見した記憶があります。
冒頭で話題にしたGoogle Meetだと、Google Meet Chat to Clipboardという拡張機能が先日配信した4.2.0で「変換中のエンターキーで送信されるのを防ぐ」機能を組みました。この記事で紹介した私作成の拡張機能ですが、データの外部送信なく、ファイルのアクセスもなく、クリップボードに入れるだけの拡張機能ですので、是非利用してみてください。
最後に
今現在(2024年4月22日17時)困っているのでGoogle Meetを題材にしましたが、欧米中心で開発されているウェブサービスにはたまにあることです。対応されるのを待つのが基本だと思いますが、クライアント(ブラウザ)で打てる手はありますよ、という紹介でした。参考になれば幸いです。