搜尋

首頁  >  問答  >  主體

javascript - tap可以解決click延遲300ms的懷疑?

click&tap

行動端大家比較推薦的寫法都是採用zepto的tap事件代替click,理由一般是click事件有傳說中的300ms延遲。

測試結果

但實際測試發現click事件還比tap事件相應快一些。

click 和 tap 觸發延遲只有100ms左右

demo

<!DOCTYPE html>
<html lang="en">
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <title>click&tap</title>
    <style type="text/css">
        * {
            margin: 0;
            padding: 0;
        }

        h3 {
            text-align: center;
            line-height: 50px;
            border-bottom: 1px solid #c7c7c7;
        }
    </style>
</head>
<body>
<h3 id="h3">click me</h3>
</body>
<script type="text/javascript" src="../../common/zepto.js"></script>
<script type="text/javascript" src="../../common/touch.js"></script>
<script type="text/javascript">
    // click 事件延迟问题
    document.getElementById('h3').addEventListener('click', function (e) {
        console.log("=========click1======")
        console.log(new Date().getTime());
    });

    $("#h3").on('tap', function (e) {
        console.log("=========zepto tap1======")
        console.log(new Date().getTime());
    });

    document.getElementById('h3').addEventListener('click', function (e) {
        console.log("=========click2======")
        console.log(new Date().getTime());
    });

    $("#h3").on('tap', function (e) {
        console.log("=========zepto tap2======")
        console.log(new Date().getTime());
    });

    document.getElementById('h3').addEventListener('touchend', function (e) {
        console.log("=========touchend======")
        console.log(new Date().getTime());
    });

    document.getElementById('h3').addEventListener('touchstart', function (e) {
        console.log("=========touchstart======")
        console.log(new Date().getTime());
    });

</script>
</html>

output

//output
click&tap.html?_ijt=jcsp6kceg9n7qagit0tsqmnrn3:56 =========touchstart======
click&tap.html?_ijt=jcsp6kceg9n7qagit0tsqmnrn3:57 1494338413993
click&tap.html?_ijt=jcsp6kceg9n7qagit0tsqmnrn3:51 =========touchend======
click&tap.html?_ijt=jcsp6kceg9n7qagit0tsqmnrn3:52 1494338414081
click&tap.html?_ijt=jcsp6kceg9n7qagit0tsqmnrn3:31 =========click1======
click&tap.html?_ijt=jcsp6kceg9n7qagit0tsqmnrn3:32 1494338414082
click&tap.html?_ijt=jcsp6kceg9n7qagit0tsqmnrn3:41 =========click2======
click&tap.html?_ijt=jcsp6kceg9n7qagit0tsqmnrn3:42 1494338414083
click&tap.html?_ijt=jcsp6kceg9n7qagit0tsqmnrn3:36 =========zepto tap1======
click&tap.html?_ijt=jcsp6kceg9n7qagit0tsqmnrn3:37 1494338414084
click&tap.html?_ijt=jcsp6kceg9n7qagit0tsqmnrn3:46 =========zepto tap2======
click&tap.html?_ijt=jcsp6kceg9n7qagit0tsqmnrn3:47 1494338414084

相關問題

在行動端採用zepto的tap事件時會有點透的現象。

原因一般是:在tap事件中關閉或隱藏了父級(一般情況下是遮罩層)的dom,而子dom恰好也存在點擊事件,這樣由於事件流機制(捕獲冒泡)導致子級dom也觸發了點擊事件。

分析:都在冒泡階段(事件觸發預設冒泡階段)的話,父級肯定比子集後觸發,應該不會產生點透現象。

有些部落格文章說父級使用tap,子集使用click。看demo中的觸發時間也不太發生這種情況。

主要是會有那個傻逼同時在一個商業邏輯中使用click和tap呢?

所以基本上感覺主要是同時使用捕獲階段觸發事件。但這樣也有一個問題,zepto的事件機制是基於事件冒泡,touch.js中事件都是綁定在document上的。

给我你的怀抱给我你的怀抱2774 天前648

全部回覆(5)我來回復

  • 天蓬老师

    天蓬老师2017-05-19 10:15:16

    都用tap 或引入fastclick.js

    回覆
    0
  • 阿神

    阿神2017-05-19 10:15:16

    建議引用fastclick.js,可以解决click事件會有300毫秒的延遲
    官網 https://github.com/ftlabs/fas...

    回覆
    0
  • 天蓬老师

    天蓬老师2017-05-19 10:15:16

    zepto的tap事件也只是模擬,而且效率也一般,自然沒有原生的click反應快。如果是比較簡單的需求(例如只需要回應「點擊」事件),可以考慮用fastclick,好處是原有的click事件處理不用改,且可以同時適配pc端和行動端。但如果只是行動端需求,那直接用原生的touchstart事件就可以了。

    另外還有一種解決想法是直接上手勢庫,比如Hammerjs或者騰訊的AlloyFinger之類的,適合有比較複雜的手勢需求的場景。

    回覆
    0
  • 巴扎黑

    巴扎黑2017-05-19 10:15:16

    為啥不考慮下touchstart

    回覆
    0
  • 黄舟

    黄舟2017-05-19 10:15:16

    修正一下你的點透事件的原因哦,不是因為冒泡機制,而是因為點擊事件的延遲。

    • 例如,點擊關閉按鈕,touchend先觸發tap,彈出層和遮罩就被隱藏了。 touchend後繼續等待300ms發現沒有其他行為了,則繼續觸發click,由於這時彈出層已經消失,所以當前click事件的target就在底層元素上,於是就觸發了底層事件內容。整個事件觸發過程為 touchend -> tap -> click。

    回覆
    0
  • 取消回覆