みかづきブログ・カスタム

基本的にはちょちょいのほいです。

iOS12以前のSafariではwindow、document、bodyにclickイベントを設定しても発火しない 🖱


mobile Safariのclcikイベントについて

その昔、iOSのmobile Safariに置いて、widnow、document、bodyにはclickイベントが設定できない記憶があったのですが、最近はどうなのか改めて調べてみました。
結論を先に書くと、iOS13以降は設定できるようになった模様です。(iOS13.5、iOS14.2にて確認)
iOS12以前では設定できませんでした。(iOS12.4、iOS11.4、iOS10.3.1にて確認)

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イベントを設定すれば良いので、この技を使わなければならないケースはすごく少ないと思います。