fastclick與zepto的 tap事件關於在手機上click事件的300ms延遲的區別

以前翻譯過一篇關於fastclick的快速點擊文章http://www.cnblogs.com/lilyimage/p/3568773.html,fastclick能夠解決在手機上點擊事件的300ms延遲;另外咱們也知道zepto的touch模塊,幫助咱們實現了不少手機上的事件,好比tap等,tap事件也是爲了解決在click的延遲問題。那麼他們有什麼區別呢?javascript

先看zepto的touch模塊實現:html

 1 $(document)
 2     .on('touchstart ...',function(e){
 3              ...
 4              ...
 5              now = Date.now()
 6              delta = now - (touch.last || now)
 7              if (delta > 0 && delta <= 250) touch.isDoubleTap = true
 8              touch.last = now
 9     })
10     .on('touchmove ...', function(e){
11     })
12     .on('touchend ...', function(e){
13            ...
14            if (deltaX < 30 && deltaY < 30) {
15                   var event = $.Event('tap')
16                 
17                   touch.el.trigger(event)
18            }
19     })                    

touch模塊綁定事件touchstart,touchmove和touchend到document上,而後經過計算touch事件觸發的時間差,位置差來實現了自定義的tap,swipe等。java

那麼tap事件爲何會「穿透」呢?git

好比下面的代碼:github

<html>
    <head>
        <meta charset="UTF-8">
        <script type="text/javascript" src="/resources/js/zepto.js"></script>
        <script type="text/javascript" src="/resources/js/zepto-touch.js"></script>
        <title></title>
    </head>
    <body>
        <style>
            .q{width: 200px;height: 200px;background-color: red;position: absolute;top:0;;left: 0}
            .b{width: 300px;height: 300px;background-color: green;position: absolute;top:0;;left: 0}
        </style>
        
        <div class="b"></div>
        <div class="q"></div>
        <script>
            $('.q').on('tap',function(e){
                $(this).hide();
            });
            $('.b').on('click',function(e){
                alert("bb");
            });
        </script>
    </body>
</html>

在手機上,點擊了q之後,就會彈出bb的彈框,爲何呢?瀏覽器

由於tap事件是經過document綁定了touchstart和touchend事件實現,$('.q')上,當touchend事件冒泡到document上之後執行$(this).hide();此時$('.b'),就處在了頁面的最前面,app

如今touchend冒泡到了document上,而且$('.b')在頁面的最前面,而後就觸發了click事件。ide

關於click事件300ms延遲的由來,以及隨着時間的發展,遇到的問題,各家瀏覽器的解決方法和如今的各類js的方法,能夠見http://blogs.telerik.com/appbuilder/posts/13-11-21/what-exactly-is.....-the-300ms-click-delay 準備翻譯下。由於裏面也介紹了fastclick,呵呵。post

今天看到了別人的翻譯稿,拿過來啦,http://thx.github.io/mobile/300ms-click-delay/ui

因此zepto的touch模塊真的不是一個好的模塊。。不過比我本身寫的好,關鍵是爲何一直都不解決這個點透的問題啊。。

fastclick呢?

它的實際原理是在目標元素上綁定touchstart ,touchend事件,而後在touchend結束的時候立馬執行click事件,這樣就解決了「點透」的問題(實質是事件冒泡致使)以及300ms延遲問題,300ms延遲是由於瀏覽器爲了實現用戶雙擊屏幕放大頁面(double tap to zoom 詳細見我下一篇翻譯吧)的效果。

FastClick.prototype.sendClick = function(targetElement, event) {
    'use strict';
    var clickEvent, touch;

    // On some Android devices activeElement needs to be blurred otherwise the synthetic click will have no effect (#24)
    if (document.activeElement && document.activeElement !== targetElement) {
        document.activeElement.blur();
    }

    touch = event.changedTouches[0];

    // 這裏就是關鍵,就是在這裏實現了click事件
    clickEvent = document.createEvent('MouseEvents');
    clickEvent.initMouseEvent(this.determineEventType(targetElement), true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);
    clickEvent.forwardedTouchEvent = true;
    targetElement.dispatchEvent(clickEvent);
};

在touchEnd的時候會立馬調用這個sendClick

FastClick.prototype.onTouchEnd = function(event){
          ......  
         this.sendClick(targetElement, event);
}

好了,這兩個就是這樣了。

相關文章
相關標籤/搜索