更新時(shí)間:2023-09-27 來(lái)源:黑馬程序員 瀏覽量:
在移動(dòng)端使用click事件時(shí)會(huì)出現(xiàn)300ms左右的延時(shí)問(wèn)題,其原因是瀏覽器需要判斷用戶的操作是單次點(diǎn)擊還是雙次點(diǎn)擊。例如,在手機(jī)上瀏覽網(wǎng)頁(yè)時(shí),由于手機(jī)屏幕比較小,頁(yè)面中可能會(huì)有一些文字看不清楚。為了看清楚文字,用戶通常會(huì)快速雙擊屏幕放大頁(yè)面查看內(nèi)容。當(dāng)用戶第一次點(diǎn)擊屏幕時(shí),瀏覽器無(wú)法立刻判斷用戶的操作,瀏覽器會(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è)解決方案,用來(lái)處理click事件出現(xiàn)300ms延時(shí)的問(wèn)題,大家可以根據(jù)實(shí)際需求進(jìn)行選擇。
1.禁用縮放解決移動(dòng)端click事件出現(xiàn)300ms的延時(shí)問(wèn)題
設(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í)無(wú)法滿足需求。
2.封裝touch事件解決移動(dòng)端click 事件出現(xiàn)300 ms的延時(shí)問(wèn)題
當(dāng)瀏覽器允許用戶縮放頁(yè)面時(shí),可以對(duì)touch事件進(jìn)行封裝,解決300ms延時(shí)問(wèn)題,具體實(shí)現(xiàn)思路如下:
①當(dāng)手指觸摸屏幕時(shí),記錄當(dāng)前觸摸開(kāi)始的時(shí)間。
②當(dāng)手指離開(kāi)屏幕時(shí),用離開(kāi)的時(shí)間減去觸摸開(kāi)始的時(shí)間,得到手指停留時(shí)間。
③如果手指停留時(shí)間小于150ms,并且沒(méi)有滑動(dòng)過(guò)屏幕,就定義為單次點(diǎn)擊。
下面編寫代碼將touch事件手動(dòng)封裝成一個(gè)tap事件,解決300ms延時(shí)問(wèn)題,示例代碼如下:
//封裝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){ // 如果手指觸摸和離開(kāi)時(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í)問(wèn)題。
3.使用FastClick 插件解決移動(dòng)端click 事件出現(xiàn)300 ms的延時(shí)問(wèn)題
FastClick 插件是由FT Labs(英國(guó)金融時(shí)報(bào)實(shí)驗(yàn)室)團(tuán)隊(duì)開(kāi)發(fā)的JavaScript庫(kù),它簡(jiǎn)單易用,容易上手,解決了click事件在移動(dòng)端觸發(fā)時(shí)有大約300ms延時(shí)的問(wèn)題。FastClick的實(shí)現(xiàn)原理是在檢測(cè)到touchend事件時(shí),通過(guò)DOM自定義事件立即觸發(fā)click事件,并阻止瀏覽器在300 ms之后的click事件。
下面講解如何使用FastClick 插件解決移動(dòng)端click事件出現(xiàn)300 ms的延時(shí)問(wèn)題,具體步驟如下。
(1)通過(guò)官網(wǎng)下載fastclick.js至本地,并在HTML頁(yè)面中使用<script>標(biāo)簽引入fastclick.js文件,引入方式如下:、
<script src="fastclick.js"></script>
(2)通過(guò)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)擊操作'); });