始めに
iOS Safariでinput要素を選択してキーボードが出ているとき、何も設定しないと画面をタップしただけではfocusを外してキーボードを閉じることができません。これを何とかするために今まではJSでblurするようにしていましたが、もっと単純な方法があったのでその方法を紹介したいと思います。
結論
親のDOMにonclickイベントを設定したら外せます。めちゃくちゃ簡単ですね(笑)。onclickの処理を書かなくても問題ないです。また、どの階層にいても問題ないので、一番上のdiv要素にonclickを設定すればいいと思います。
<html>
<body>
<!-- 親要素に空でもいいのでonclickの設定をする -->
<div onclick="">
<input text="" />
</div>
</body>
</html>
なぜこれで上手くいくか
仕様をちゃんと読んだわけではないので憶測ですが、どうやらonclickイベントを設定していないDOMはこのイベント自体を省略してしまうようです。HTMLの挙動的にはどれかをクリックしたらそちらにfocusが移るのですが、イベント自体が省略されているのでfocusが外れないようです。
なので一番親であるdiv要素とかにonclickイベントを設定することで必ずonclickイベントを拾えるようになるので、focusを外せるということです。(bodyタグでいけるかと思ったのですが、どうやらbodyだと拾ってくれなそうです)
サンプルコード
CodePenでサンプルコードを書きましたのでそれをこちらに載せます。
See the Pen iOSでフォーカスを簡単に外す by wintyo (@wintyo) on CodePen.
スマホで動作を確認する方は以下のURLからアクセスしたほうがいいと思います。
https://codepen.io/wintyo/full/wLbqLN
一番上にbodyのクリックイベントをカウントするようにしましたが、カウントされていない場所があると思います。そこはクリックイベントが送られていないのでfocusも外せない状態になっています。
ついでの発見ですが、どうやらonclickイベントを拾った要素にハイライトカラーが当たるようですね。実際はこれは邪魔だと思うのでハイライトカラーを消さないといけなそうですね。
終わりに
iOS Safariでfocusが外せない問題に結構悩まされていましたが、簡単に対応できる方法が見つかってよかったです。ただこのサンプルコードを書いていたら勝手にズームされたり、キーボード表示中にスクロールすると謎の黒い領域が現れたり、iOS特有の挙動に悩まされてしまいました。ズームはなんとかなりましたが、領域のほうは解決できませんでした・・・。もうちょっと普通の挙動をしてくれると嬉しいんですけどねぇ。