どもです。
バーコードリーダをBluetoothでスマホに接続するタイプのウェブシステムを作っていたのですが、いざ実機(AndroidのGoogleChrome)で動かしてみると稀にホーム画面に飛んでしまう。なにゆえ?
再現条件を調査したところ、
①alertでOKを押した直後、またはalertのフォーカスを外した直後
②Enterに相当するキー(CR)が入力されると
③ブラウザのツールバーの先頭(最左)が実行される
らしい。
アプリのChromeでは先頭がホームへのリンクのため、ホームに飛んでしまったわけです。
ホームへのリンクを非表示にしたところ、今度はURL欄の「サイト情報を表示」がヒットしました。
しかもこの現象、同じサイト上でも起きるページと起きないページがあるのです。
どうやらアラートウィンドウのOKボタンに初めからフォーカスが当たっている場合と無い場合があり、当たっている場合がアウトのよう。この差はなんだ。
…
$(document).keypress(function(){})で着火しているとアウトッッッ!!!
以前、iPhoneで検証したページをマイナーな実機で起動したら、$(document).keypress(function(){})が着火しなかった事件、あったなぁ…。(遠い目)
今回は.keypressで着火はOK、その後の処理も概ね問題なく、アラート時のフォーカスだけがバグった、と。
ちなみに.keypressを.keyupや.keydown、.addEventListener('keypress')などにしても同じで、documentをwindowや$('html')などのフォーカスしない対象にしてもNG。
また、ツールバー操作直後のEnterでイベントの発火が確認できたため、本件は仕様ではなく.keypressとalert()に類するものが絡んだ場合にのみ発生する、限定的なバグだと確信できました。
おかげでggってもAndroidのChromeでフォーカスがツールバーやアドレスバーに飛ぶなんて話、ひとっっつも出てこねーです。
まーね、普通はスマホでinputやtextarea以外で.keypressイベントを着火する機会なんて無いからね。かつalert()とか一般のウェブサイトじゃ使わないもの。こんな弩マイナーな不具合を誰が見つけるんだって話なのは重々承知。Googleに文句言っても仕方あるめぇ。
さて、着火してからフォーカスを別の要素に当てる、イベントの着火をボタンに移してトリガーを実行するなど、色々回避を試してみましたが、全敗。どうにもこすい真似は許してくれないようで。
今回は一般向けのサービスでなく、使用する機体が決まっているため、$(document).keypress(function(){})の着火まではできるという前提でアラート画面もどきを作成。バグのトリガーとなるalert()を回避する対策としました。
$(document).keypress(function(){})自体を避ける場合、都度フォーカスをテキストエリアに持っていくことになりますが、見た目や動作がもっさりしてしまうんですよねぇ…。(経験済み)