web-dev-qa-db-ja.com

モバイルSafariでクリックイベントの300ミリ秒の遅延を解消

私はそれを読みました モバイルSafariではクリックイベントで300ミリ秒の遅延があります リンク/ボタンがクリックされてからイベントが発生するまで。遅延の理由は、ユーザーがダブルクリックするかどうかを確認するために待機することですが、UXの観点からは、300ミリ秒待機することは望ましくないことがよくあります。

1つのソリューション この300ミリ秒の遅延を解消するには、jQuery Mobileの「タップ」処理を使用します。残念ながら、私はこのフレームワークに精通しておらず、必要なのがtouchendを適切な方法で適用する1行または2行のコードだけである場合、大きなフレームワークをロードしたくありません。

多くのサイトと同様に、私のサイトには次のような多くのクリックイベントがあります。

$("button.submitBtn").on('click', function (e) {   
  $.ajaxSubmit({... //ajax form submisssion
});

$("a.ajax").on('click', function (e) {   
  $.ajax({... //ajax page loading
});

$("button.modal").on('click', function (e) {   
      //show/hide modal dialog
});

そして、私がやりたいのは、ALL300ミリ秒の遅延を取り除くことです。このような単一のコードスニペットを使用して:

$("a, button").on('tap', function (e) {
 $(this).trigger('click');
 e.preventDefault();
});

それは悪い/良いアイデアですか?

84
tim peterson

現在、一部のモバイルブラウザーでは、ビューポートを設定した場合にクリック遅延300ミリ秒が解消されています。回避策を使用する必要はもうありません。

<meta name="viewport" content="width=device-width, user-scalable=no">

これは現在でサポートされていますChrome for AndroidFirefox for AndroidおよびSafari iOS向け

ただし、iOS Safariでは、ダブルタップはズームできないページでのスクロールジェスチャーです。そのため、300msの遅延を削除できません。ズームできないページの遅延を削除できない場合、ズーム可能なページの遅延を削除する可能性は低くなります。

Windows Phoneもズーム不可能なページで300ミリ秒の遅延を保持しますが、iOSのような代替ジェスチャーがないため、Chromeとしてこの遅延を削除することができます_持っています。 次を使用して、Windows Phoneの遅延を削除できます。

html {
-ms-touch-action: manipulation;
touch-action: manipulation;
}

ソース: http://updates.html5rocks.com/2013/12/300ms-tap-delay-gone-away

2015年12月更新

これまで、iOSのWebKitとSafariでは、シングルタップでリンクまたはボタンがアクティブになり、ダブルタップでページを拡大できるまでに350ミリ秒の遅延がありました。 Chromeは、数か月前にこれを変更するために、よりスマートなアルゴリズムを使用してそれを検出し、 WebKitは同様のアプローチで追跡します 。この記事では、ブラウザーがタッチジェスチャでどのように機能し、ブラウザーが現在よりもはるかにスマートになる方法について、いくつかの優れた洞察を提供します。

2016年3月更新

IOSのSafariでは、「高速タップ」応答を作成するために、2番目のタップを検出するための350ミリ秒の待機時間が削除されました。これは、width = device-widthまたはuser-scalable = noでビューポートを宣言するページで有効になります。作成者は、CSS touch-action: manipulationを使用して特定の要素の高速タップ動作を選択することもできます here ( 'Styling Fast-Tap Behavior'見出しまでスクロールダウン)および ここ

61
NoNameProvided

このプラグイン-Financial Timesによって開発されたFastClick はあなたにぴったりです!

ただし、クリック関数の直後にevent.stopPropagation();および/またはevent.preventDefault();を追加してください。そうしないと、2回実行される可能性があります。

$("#buttonId").on('click',function(event){
    event.stopPropagation(); event.preventDefault();
   //do your magic

});
43
Jonathan

これは古いことは知っていますが、ブラウザで「タッチ」がサポートされているかどうかをテストすることはできませんか?次に、「タッチエンド」または「クリック」の変数を作成し、その変数を要素にバインドされるイベントとして使用しますか?

var clickOrTouch = (('ontouchend' in window)) ? 'touchend' : 'click';
$('#element').on(clickOrTouch, function() {
    // do something
});

そのため、サンプルコードでは、ブラウザで「タッチエンド」イベントがサポートされているかどうかを確認し、サポートされていない場合は「クリック」イベントを使用します。

(編集:「touchend」を「ontouchend」に変更)

16

Hammer.jsと呼ばれる非常に人気のある代替手段(Githubページ) に出会いましたが、これが最良のアプローチだと思います。

Hammer.jsは、Fastclick.js(最も投票された回答)よりもフル機能のタッチライブラリです(多くのスワイプコマンドがあります)。

しかし、注意してください:モバイルデバイスでの高速スクロールは、Hammer.jsまたはFastclick.jsのいずれかを使用すると、UIを本当にロックする傾向があります。これは、サイトにユーザーが頻繁にスクロールするニュースフィードまたはインターフェイスがある場合(ほとんどのWebアプリのように見える)、大きな問題です。このため、現時点ではこれらのプラグインを使用していません。

12
tim peterson

どういうわけか、ズームを無効にすると、この小さな遅延が無効になるようです。ダブルタップはもう必要ないので、理にかなっています。

モバイルWebページでズームを「無効」にするにはどうすればよいですか?

しかし、これがもたらすユーザビリティへの影響に注意してください。アプリとして設計されたWebページには便利かもしれませんが、より汎用的な「静的」ページには使用しないでください。低遅延が必要なペットプロジェクトに使用します。

2
ayke

Jqueryとfastclickライブラリなしで簡単な方法を探しました。これは私のために働く:

var keyboard = document.getElementById("keyboard");
var buttons = keyboard.children;
var isTouch = ("ontouchstart" in window);
for (var i=0;i<buttons.length;i++) {
    if ( isTouch ) {
        buttons[i].addEventListener('touchstart', clickHandler, false);         
    } else {
        buttons[i].addEventListener('click', clickHandler, false);          
    }
}
1

残念ながら、これを行う簡単な方法はありません。したがって、touchstartまたはtouchendを使用するだけでは、たとえばボタンをクリックしたときに誰かがスクロールを開始するなど、他の問題が残ります。 zepto をしばらく使用しますが、この非常に優れたフレームワークを使用しても、時間の経過とともにいくつかの問題が発生します。それらの多くは closed ですが、単純な解決策の分野ではないようです。

リンクのクリックをグローバルに処理するこのソリューションがあります。

   $(document.body).
    on('tap', 'a',function (e) {
      var href = this.getAttribute('href');
      if (e.defaultPrevented || !href) { return; }
      e.preventDefault();
      location.href= href;
    }).
    on('click', 'a', function (e) {
      e.preventDefault();
    });
1

JQueryでは、「touchend」イベントをバインドし、タップ後すぐにトリガーコードを切り替えることができます(キーボードのキーダウンのようなものです)。現在のChromeおよびFirefoxタブレットバージョンでテスト済み。タッチスクリーンのラップトップおよびデスクトップデバイスの「クリック」も忘れないでください。

jQuery('.yourElements').bind('click touchend',function(event){

    event.stopPropagation();
    event.preventDefault();

        // everything else
});
0
Benjamin

パッシブモードを明示的に宣言することになっています :

window.addEventListener('touchstart', (e) => {

    alert('fast touch');

}, { passive : true});
0
Bruno

追加情報を提供するだけです。

IOS 10では、ページの<button>sを継続的にトリガーできませんでした。常に遅れがありました。

Fastclick/Hammer/tapjs/clickをtouchstartに置き換えてみましたが、すべて失敗しました。

更新:理由は、ボタンがエッジに近すぎることです!それを中心近くに移動し、遅れがなくなりました!

0
Dai