mobile Safariのclcikイベントについて
その昔、iOSのmobile Safariに置いて、widnow、document、bodyにはclickイベントが設定できない記憶があったのですが、最近はどうなのか改めて調べてみました。
結論を先に書くと、iOS13以降は設定できるようになった模様です。(iOS13.5、iOS14.2にて確認)
iOS12以前では設定できませんでした。(iOS12.4、iOS11.4、iOS10.3.1にて確認)
DEMO
HTML
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>click</title> <style> body { position: fixed; top: 0; bottom: 0; left: 0; right: 0; } </style> </head> <body> <script> window.addEventListener('click', () => { alert('window'); }); document.addEventListener('click', () => { alert('document'); }); document.body.addEventListener('click', () => { alert('body'); }); </script> </body> </html>
検証に使用したコードです。
bodyの領域を広げるためにposition: fixedを設定している以外は何もしていません。
対策 その1
clickではなく、touchstartやtouchendであればiOS12以前でも発火するので、大急ぎで修正する場合はどちらかを使っても良いでしょう。
対策 その2
touchstartやtouchendではなく、どうしても、widnow、document、bodyに設定したclickイベントを発火させたい場合、そんな時はイベントの伝搬を使うと良いです。
なぜならば、widnow、document、bodyでも伝搬したイベントはキャッチできるかたですの。
具体的には、
HTML
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>click</title> <style> body, #event { position: fixed; top: 0; bottom: 0; left: 0; right: 0; } </style> </head> <body> <div id="event"></div> <script> window.addEventListener('click', () => { alert('window'); }); document.addEventListener('click', () => { alert('document'); }); document.body.addEventListener('click', () => { alert('body'); }); document.getElementById('event').addEventListener('click', () => {}); </script> </body> </html>
という感じで、clickイベントを設定したDOMを置くことで、body、document、windowの順にclickイベントが発火するようになります。
(iOS10.3.1、iOS11.4、iOS12.4、iOS13.5、iOS14.2にて確認)
DEMO
develop.kimizuka.org
ただ、これだったらDOM(今回の場合は#event)にclickイベントを設定すれば良いので、この技を使わなければならないケースはすごく少ないと思います。