移動端300ms延遲由來及解決方案


1、300ms延遲由來

300 毫秒延遲的主要原因是解決雙擊縮放(double tap to zoom)。雙擊縮放,顧名思義,即用手指在屏幕上快速點擊兩次,iOS 自帶的 Safari 瀏覽器會將網頁縮放至原始比例。 那么這和 300 毫秒延遲有什么聯系呢? 假定這么一個場景。用戶在 iOS Safari 里邊點擊了一個鏈接。由於用戶可以進行雙擊縮放或者雙擊滾動的操作,當用戶一次點擊屏幕之后,瀏覽器並不能立刻判斷用戶是確實要打開這個鏈接,還是想要進行雙擊操作。因此,iOS Safari 就等待 300 毫秒,以判斷用戶是否再次點擊了屏幕。 鑒於iPhone的成功,其他移動瀏覽器都復制了 iPhone Safari 瀏覽器的多數約定,包括雙擊縮放,幾乎現在所有的移動端瀏覽器都有這個功能。、

 

2、解決方案

(1)添加viewpoint meta標簽

<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />

(2)FastClick

https://github.com/ftlabs/fastclick

移動端事件觸發順序:在移動端,手指點擊一個元素,會經過:touchstart --> touchmove -> touchend -->click。

fastclick.js的原理是:FastClick的實現原理是在檢測到touchend事件的時候,會通過DOM自定義事件立即出發模擬一個click事件,並把瀏覽器在300ms之后真正的click事件阻止掉。

 fastclick同樣可以解決移動端點透現象。

點透現象:當A/B兩個層上下z軸重疊,上層的A點擊后消失或移開(這一點很重要),並且B元素本身有默認click事件(如a標簽)或綁定了click事件。在這種情況下,點擊A/B重疊的部分,就會出現點透的現象。點透現象的關鍵點:

A/B兩個層上下z軸重疊。

上層的A點擊后消失或移開。(這一點很重要)

B元素本身有默認click事件(如a標簽) 或 B綁定了click事件。

在以上情況下,點擊A/B重疊的部分,就會出現點透的現象。

示例代碼:

<!doctype html>
<html lang="en">

    <head>
        <meta charset="UTF-8">
        <title>移動端點透現象</title>
        <style> * { margin: 0px; padding: 0px;
            } #div1 {
                /*紅色半透明遮蓋層A*/ width: 300px; height: 300px; background-color: rgba(255, 0, 0, 0.25);
            } #div2 {
                /*黃色內容層B*/ width: 240px; height: 240px; background-color: yellow; position: absolute; left: 30px; top: 30px; z-index: -1;
            } #console {
                /*綠色狀態輸出框*/ border: 1px solid green; position: absolute; top: 300px; width: 100%;
            }
        </style>
    </head>

    <body>
        <div id="div1"></div>
        <div id="div2">
            <a href="https://www.baidu.com/">www.baidu.com</a>
        </div>
        <div id="console"></div>
        <script type="text/javascript">
            var div1 = document.getElementById("div1"); var div2 = document.getElementById('div2'); function handle(e) { var tar = e.target,          eve = e.type; console.log("target:" + tar.id + " event:" + eve) if(tar.id === "div1") { div1.style.display = "none"; } } div1.addEventListener("touchend", handle); div1.addEventListener("touchstart", handle); div2.addEventListener('click', handle); </script>
    </body>

</html>

解決方法:

<!doctype html>
<html lang="en">

    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
        <title>移動端點透現象解決方法</title>
        <style> * { margin: 0px; padding: 0px;
            } #div1 {
                /*紅色半透明遮蓋層A*/ width: 300px; height: 300px; background-color: rgba(255, 0, 0, 0.25);
            } #div2 {
                /*黃色內容層B*/ width: 240px; height: 240px; background-color: yellow; position: absolute; left: 30px; top: 30px; z-index: -1;
            } #console {
                /*綠色狀態輸出框*/ border: 1px solid green; position: absolute; top: 300px; width: 100%;
            }
        </style>
    </head>

    <body>
        <div id="div1"></div>
        <div id="div2">
            <a href="https://www.baidu.com/">www.baidu.com</a>
        </div>
        <div id="console"></div>
        <script src="https://cdn.bootcss.com/fastclick/1.0.6/fastclick.min.js"></script>
        <script type="text/javascript">
            if('addEventListener' in document) { document.addEventListener('DOMContentLoaded', function() { FastClick.attach(document.body); }, false); } var div1 = document.getElementById("div1"); var div2 = document.getElementById('div2'); function handle(e) { var tar = e.target,          eve = e.type; console.log("target:" + tar.id + " event:" + eve) if(tar.id === "div1") { div1.style.display = "none"; } } div1.addEventListener("touchend", handle); div1.addEventListener("touchstart", handle); div2.addEventListener('click', handle); </script>
    </body>

</html>

說明:手機端瀏覽器基本已經沒有300ms延時現象。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM