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 (10) 作業実績 (10) C++ (5) Webアプリ (5) Linux (4) PHP (4) JavaScript (3) laravel (3) 書籍 (2) プログラミング (2) ネットワーク (2) Nginx (2) Vue.js (2) Golang (2) EC-CUBE (2) C (1) デモ (1) CreateJS (1) AWS (1)

技術的な情報は以下にもあります。