首頁(yè)常見問題正文

怎樣解決移動(dòng)端click事件的延時(shí)問題?

更新時(shí)間:2023-09-27 來源:黑馬程序員 瀏覽量:

1695724505873_黑馬程序員好口碑IT教育.gif

在移動(dòng)端使用click事件時(shí)會(huì)出現(xiàn)300ms左右的延時(shí)問題,其原因是瀏覽器需要判斷用戶的操作是單次點(diǎn)擊還是雙次點(diǎn)擊。例如,在手機(jī)上瀏覽網(wǎng)頁(yè)時(shí),由于手機(jī)屏幕比較小,頁(yè)面中可能會(huì)有一些文字看不清楚。為了看清楚文字,用戶通常會(huì)快速雙擊屏幕放大頁(yè)面查看內(nèi)容。當(dāng)用戶第一次點(diǎn)擊屏幕時(shí),瀏覽器無法立刻判斷用戶的操作,瀏覽器會(huì)等待300ms。如果用戶在300ms內(nèi)再次點(diǎn)擊了屏幕,瀏覽器就會(huì)認(rèn)為是一個(gè)雙次點(diǎn)擊的操作,否則就會(huì)認(rèn)為是一個(gè)單次點(diǎn)擊操作。

隨著移動(dòng)端網(wǎng)頁(yè)的流行與普及,用戶對(duì)網(wǎng)頁(yè)性能有了更高的要求,而在移動(dòng)端使用click事件會(huì)出現(xiàn)延時(shí),這會(huì)影響用戶的體驗(yàn)。下面我們給出了3個(gè)解決方案,用來處理click事件出現(xiàn)300ms延時(shí)的問題,大家可以根據(jù)實(shí)際需求進(jìn)行選擇。

1.禁用縮放解決移動(dòng)端click事件出現(xiàn)300ms的延時(shí)問題

設(shè)置瀏覽器禁用默認(rèn)的雙擊縮放即可去掉300ms的點(diǎn)擊延時(shí),示例代碼如下:

<meta name="viewport" content="user-scalable=no">
上述代碼中,使用user-scalable=no表明這個(gè)頁(yè)面不可縮放,此時(shí)瀏覽器就會(huì)禁用雙擊縮放并且去掉300ms點(diǎn)擊延時(shí)。但這個(gè)方案存在缺點(diǎn),它完全禁用了雙擊縮放,當(dāng)我們需要放大文字或者圖片時(shí)無法滿足需求。

2.封裝touch事件解決移動(dòng)端click 事件出現(xiàn)300 ms的延時(shí)問題

當(dāng)瀏覽器允許用戶縮放頁(yè)面時(shí),可以對(duì)touch事件進(jìn)行封裝,解決300ms延時(shí)問題,具體實(shí)現(xiàn)思路如下:

①當(dāng)手指觸摸屏幕時(shí),記錄當(dāng)前觸摸開始的時(shí)間。

②當(dāng)手指離開屏幕時(shí),用離開的時(shí)間減去觸摸開始的時(shí)間,得到手指停留時(shí)間。

③如果手指停留時(shí)間小于150ms,并且沒有滑動(dòng)過屏幕,就定義為單次點(diǎn)擊。

下面編寫代碼將touch事件手動(dòng)封裝成一個(gè)tap事件,解決300ms延時(shí)問題,示例代碼如下:

//封裝tap事件
function tap(obj,callback) {
  var isMove=false;           
//記錄手指是否移動(dòng)
  var startTime=0;            //記錄觸摸時(shí)的時(shí)間變量
  obj.addEventListener('touchstart',function(e){
    startTime=Date.now();
}):  //記錄觸摸時(shí)間
  });
obj.addEventListener('touchmove',function (e){
    isMove=true;              //查看手指是否有滑動(dòng)(如果有,屬于拖曳,不屬于點(diǎn)擊)
  });
  obj.addEventListener('touchend',function (e){
if(!isMove &6 (Date.now()-startTime)<150){
       // 如果手指觸摸和離開時(shí)間小于150ms,屬于點(diǎn)擊
         callback && callback();//執(zhí)行回調(diào)函數(shù)
    }
    isMove=false;                  // 取反
    startTime=0;
  });
}
// 調(diào)用
tap(div,function(){
//執(zhí)行點(diǎn)擊后的代碼
});

上述方案可以檢測(cè)單個(gè)元素發(fā)生點(diǎn)擊時(shí)的狀態(tài),解決移動(dòng)端click事件出現(xiàn)300ms的延時(shí)問題。

3.使用FastClick 插件解決移動(dòng)端click 事件出現(xiàn)300 ms的延時(shí)問題

FastClick 插件是由FT Labs(英國(guó)金融時(shí)報(bào)實(shí)驗(yàn)室)團(tuán)隊(duì)開發(fā)的JavaScript庫(kù),它簡(jiǎn)單易用,容易上手,解決了click事件在移動(dòng)端觸發(fā)時(shí)有大約300ms延時(shí)的問題。FastClick的實(shí)現(xiàn)原理是在檢測(cè)到touchend事件時(shí),通過DOM自定義事件立即觸發(fā)click事件,并阻止瀏覽器在300 ms之后的click事件。

下面講解如何使用FastClick 插件解決移動(dòng)端click事件出現(xiàn)300 ms的延時(shí)問題,具體步驟如下。

(1)通過官網(wǎng)下載fastclick.js至本地,并在HTML頁(yè)面中使用<script>標(biāo)簽引入fastclick.js文件,引入方式如下:、

<script src="fastclick.js"></script>

(2)通過JavaScript方式對(duì)Fastclick進(jìn)行實(shí)例化,示例代碼如下:

  if('addEventListener'in document){
    document.addEventListener ('DOMContentLoaded', function () {
      FastClick.attach(document.body);
    }, false);
  }

上述代碼中,F(xiàn)astClick.attach()方法的參數(shù)可以是任意的DOM元素,在這里使用document.body表示將body元素中的所有子元素都綁定FastClick事件,解決移動(dòng)端click。

(3)在HTML頁(yè)面中,編寫結(jié)構(gòu)代碼,示例代碼如下:

<body>
  <div></div>
</body>

(4)在<script>標(biāo)簽中的Fastclick實(shí)例化代碼后,編寫JavaScript代碼,綁定click事件,示例代碼如下:

var Odiv=document.querySelector('div');
Odiv.addEventListener('click', function(){
  alert('點(diǎn)擊操作');
});


分享到:
在線咨詢 我要報(bào)名
和我們?cè)诰€交談!