Home > ブログ > iOS13での連続したtouchstartイベント

ブログ

iOS13での連続したtouchstartイベント

今さらですが、iOS13になってからSafariで画面を連続タップした場合に、touchstartイベントが連続して発生しなくなりました。連続タップしても最初の一回のみtouchstartイベントが発生し、しばらく時間をおいてからでないと次のtouchstartイベントが発生しません。

この現象はhttps://forums.developer.apple.com/thread/125073などでも報告されています。

touchstartイベントが連続発生しないと、Webアプリケーションでダブルタップを検出したい時などで問題になります。

対策としてはいろいろと問題はあります(以下で説明)が、touchendイベントでpreventDefault()を呼び出すという手があります。

対策1(まだ不完全)

  document.addEventListener('touchend', function (e) {
    e.preventDefault();
  }, false);

これで〜iOS12と同じようにtouchstartが連続発生するようになります。

ただし、このままでは画面上の要素をクリックしてもclickイベントが発生しなくなるという別の問題が発生します。このため、touchendでイベント発行元の要素をチェックして、クリック可能な要素だった場合はpreventDefault()を呼ばないようにします。

対策2

  document.addEventListener('touchend', function (e) {
    var tagName = e.target.tagName.toLowerCase();
    if (tagName != 'a') {
      e.preventDefault();
    }
  }, false);

上記対策では<a>タグがイベント発生元だった場合は、preventDefault()を呼ばないので、<a>タグをクリック時にclickイベントが発生するようになります。アプリケーションの内容によって、button,inputタグ等もpreventDefault()の対象外にすればいいと思います。これで、touchstartイベントの連続発生とclickイベントの発生を両立させることができました。

さらにタグの種類でまとめてではなく、要素ごとに個別にクリック可能指定をしたい場合は、以下のようにできます。

対策3

  document.addEventListener('touchend', function (e) {
    var tagName = e.target.tagName.toLowerCase();
    if (!e.target.dataset.clickable &&
        tagName != 'a') {
      e.preventDefault();
    }
  }, false);

対策3 - クリック可能要素の指定

  <div onclick="msg('clicked');" data-clickable="1">clickable node</div>

クリック可能にしたい要素にdata-clickable="1"属性を指定して、touchend内でこの属性をチェックするようにしています。

このようにtouchstartイベントが連続発生しない問題に対処することができます。

iOSのSafariはバージョン毎にころころと動作が変わるのでやっかいです。Chromeではほぼ動作は変わらないんですけどね。最近またこのあたりを触る機会があり、忘れかけていたので備忘録がてらまとめました。

投稿日:2020/05/28 23:00

タグ: Webアプリ JavaScript

Top

アーカイブ

タグ

Server (28) 作業実績 (21) PHP (19) ネットワーク (17) プログラミング (15) OpenSSL (10) C (8) C++ (8) PHP関連更新作業 (8) EC-CUBE (7) Webアプリ (7) laravel (6) 書籍 (5) Nginx (5) Linux (5) AWS (4) Vue.js (4) JavaScript (4) 与太話 (4) Rust (3) Symfony (2) お知らせ (2) Golang (2) OSS (1) MySQL (1) デモ (1) CreateJS (1) Apache (1)