2016-01-20 7 views
14

モバイルブラウザのタップで300msの遅延を回避したいので、大きなリンクのあるページでFastClickを使用しています。私は、リンクの:active州のための "ハイライト"スタイルを持っていて、それはFastClickのおかげですぐに適切に発砲しています。スクロールでfastclickが「アクティブ」状態になるのを防ぐ方法はありますか?

私の問題は、モバイル・サファリでは少なくとも、ページをスクロールしてスクロールしている間に起動するということです。これにより、リンクをタップしようとしていると思わずにページをスクロールできないように感じられます。

誰かがスクロールすると発砲するのを防ぐ方法はありますか?

答えて

2

身体にneedsclickクラスを追加することはできますか?

<body class="needsclick"> 

... 

</body> 

ジャストアイデア:)

+0

感謝を助けます。 –

2

ニースの質問! +1

この問題はFastClickとは関係ありませんが、FastClickは問題の解決をより複雑にします。したがって、私は純粋なJavaScriptと生のタッチイベントに固執するでしょう)

モバイルタッチデバイスでは、webviewの実装は、プラットフォーム固有の理由でデスクトップのWebブラウザと大きく異なります。 この場合重要な機能の1つは、Webビューでのモーメンタムスクロールです。 モーメンタムスクロールは、デバイスのハードウェアアクセラレーション機能です。スクロール可能領域に画面がタッチされると、ハードウェアはタッチを識別し、スクロール可能な領域に200ミリ秒のカウントダウンタイマーを付加します。トリガーされると、領域がハードウェアアクセラレーションされたスクロールになります。ハードウェアが状態にあるとき、ハードウェアアクセラレーションされたスクロールに固有のものであるため、タッチイベントをブロードキャストしません。タイマーをキャンセルし、200ミリ秒以内にtouchイベントのpreventDefaultを使用してモーメンタムスクロールを防止しました。

ここで私はこの問題に近づいています。たとえば、overflow:scrollというネイティブスクロールを使用しているとします。 このメソッドは、タッチ可能な要素にtouchstartイベントをアタッチすることです。 touchstartイベントが発生すると、イベントハンドラは、touchend,touchmove、およびtouchcancelイベントをターゲット要素に関連付けます。 140ms後に新たに追加されたイベントを削除するsetTimoutタイマーが開始されます。ここで

は私の生産コードのためのいくつかのクリップです: 私はコレクションからイベントを追加および削除する2つのイベントメソッドがあります:

var eventify = (function() { 
    function eventify(type, el, callback, phase) { 
     phase = phase || false; 
     if ((el.constructor.toString().contains('NodeList')) || (el.constructor.toString().contains('HTMLCollection'))) { 
      [].forEach.call(el, function (element) { 
       if (!element.hasEvent(type)) { 
        element.addEvent(type); 
        HTMLElement.prototype.addEventListener.apply(element, [type, callback, phase]); 
       } 
      }); 
     } else { 
      if (!el.hasEvent(type)) { 
       el.addEvent(type); 
       HTMLElement.prototype.addEventListener.apply(el, [type, callback, phase]); 
      } 
     } 
     return callback; 
    } 

    return eventify 
})(); 

var uneventify = (function() { 
    function uneventify(type, el, callback) { 
     if ((el.constructor.toString().contains('NodeList')) || (el.constructor.toString().contains('HTMLCollection'))) { 
      [].forEach.call(el, function (element) { 
       if (element.hasEvent(type)) { 
        element.removeEvent(type); 
        HTMLElement.prototype.removeEventListener.apply(element, [type, callback]); 
       } 
      }); 
     } else { 
      if (el.hasEvent(type)) { 
       el.removeEvent(type); 
       HTMLElement.prototype.removeEventListener.apply(el, [type, callback]); 
      } 
     } 
    } 

    return uneventify 
})(); 

をそれから私は、スクロールのタップイベントのtapify方法を持っています

var tapify = (function() { 
    function tapify(el, callback) { 
     eventify('touchstart', el, function (e) { 
      var that = this; 
      var start = e.pageY; 
      var target = e.target; 
      function dynamicEvents() { 
       var endfn = eventify('touchend', target, function (evt) { 
        e.preventDefault(); 
        e.stopImmediatePropagation(); 
        evt.preventDefault(); 
        evt.stopImmediatePropagation(); 
        uneventify('touchmove', target, movefn); 
        uneventify('touchend', target, endfn); 
        uneventify('touchcancel', target, cancelfn); 
        callback && callback(target); 
       }); 
       var cancelfn = eventify('touchcancel', target, function (evt) { 
        e.preventDefault(); 
        e.stopImmediatePropagation(); 
        evt.preventDefault(); 
        evt.stopImmediatePropagation(); 
        uneventify('touchmove', target, movefn); 
        uneventify('touchend', target, endfn); 
        uneventify('touchcancel', target, cancelfn); 
        callback && callback(target); 
       }); 
       var movefn = eventify('touchmove', target, function (evt) { 
        var distance = start - evt.pageY; 
        if (distance > 20) { 
         uneventify('touchend', target, endfn); 
         uneventify('touchcancel', target, cancelfn); 
         uneventify('touchmove', el, movefn); 
        } 
       }); 
       setTimeout(function() { 
        uneventify('touchmove', target, movefn); 
        uneventify('touchend', target, endfn); 
        uneventify('touchcancel', target, cancelfn); 
       }, 140); 
      } 
      if (global.isIos) setTimeout(function() { 
       dynamicEvents(); 
      }, 60); 
      else dynamicEvents(); 
     }, false); 
    } 
    return tapify; 
})(); 

global.isIosを使用してターゲットデバイスを識別しています。 AndroidはタッチイベントをWebビューアで200ms送信するのをやめます。その後

、要素または要素のコレクションを使用したイベントを添付する:

tapify(document.querySelectorAll('button'), function (e) { 
     //your event handler here!! 
}); 

希望、これはそれが実際にすべてのコントロールのために働いてからFastClickを妨げる...

+0

この同じ方法をネイティブスクロールサーフェス上のスワイプおよびドラッグイベントに使用することは可能です。 –

+0

返信いただきありがとうございます! 今、私はFastClickと互換性のあるものを試してみたいと思っていました.JSの初心者として、私はあなたの答えを頭に浮かべていますが、FastClickとの接続方法は見ていません。 しかし、私が勇気づけられたら、あなたのコードを自分のプロジェクトに追加しようとします。 –

+0

私はあなたがそれを必要とし、document.bodyではない要素にのみFastClickを添付することをお勧めします –

関連する問題