摘要:但這樣副作用也很大,移動(dòng)端的交互體驗(yàn)全靠觸摸,將會(huì)干擾其他交互行為的處理,例如滾動(dòng)拖拽等。方案模擬修復(fù)法既然瀏覽器有這的延遲,那么我們來(lái)代替瀏覽器判斷,手動(dòng)觸發(fā)事件,這也是的解決方案。
眾所周知,移動(dòng)端在處理點(diǎn)擊事件的時(shí)候,會(huì)有300毫秒的延遲。恰恰是這300毫秒的延遲,會(huì)讓人有一種卡頓的體驗(yàn)。
這300毫秒的原因,在于早期瀏覽器的實(shí)現(xiàn)中,瀏覽器不知道用戶觸摸后,到底想做什么,所以故意等待300毫秒,再觸發(fā)click事件。
既然我們已經(jīng)知道了原因了,怎么解決呢?
方案1-粗暴治標(biāo)法因?yàn)闉g覽器對(duì)click事件的處理,有300ms的延遲,而touchstart幾乎是立即執(zhí)行的,估將所有click事件的監(jiān)聽(tīng),改為touchstart事件的監(jiān)聽(tīng),即可消除這300ms的延遲。
但這樣副作用也很大,移動(dòng)端的交互體驗(yàn)全靠觸摸,touchstart將會(huì)干擾其他交互行為的處理,例如滾動(dòng)、拖拽等。
方案2-模擬修復(fù)法既然瀏覽器有這300ms的延遲,那么我們來(lái)代替瀏覽器判斷,手動(dòng)觸發(fā)click事件,這也是fastClick的解決方案。
fastClick的核心代碼
FastClick.prototype.onTouchEnd = function(event){ // 一些狀態(tài)監(jiān)測(cè)代碼 // 從這里開(kāi)始, if (!this.needsClick(targetElement)) { // 如果這不是一個(gè)需要使用原生click的元素,則屏蔽原生事件,避免觸發(fā)兩次click event.preventDefault(); // 觸發(fā)一次模擬的click this.sendClick(targetElement, event); } }
這里可以看到,F(xiàn)astClick在touchEnd的時(shí)候,在符合條件的情況下,主動(dòng)觸發(fā)了click事件,這樣避免了瀏覽器默認(rèn)的300毫秒等待判斷。為了防止原生的click被觸發(fā),這里還通過(guò)event.preventDefault()屏蔽了原生的click事件。
我們來(lái)看看他是怎么模擬click事件的
FastClick.prototype.sendClick = function(targetElement, event) { // 這里是一些狀態(tài)檢查邏輯 // 創(chuàng)建一個(gè)鼠標(biāo)事件 clickEvent = document.createEvent("MouseEvents"); // 初始化鼠標(biāo)事件為click事件 clickEvent.initMouseEvent(this.determineEventType(targetElement), true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null); // fastclick的內(nèi)部變量,用來(lái)識(shí)別click事件是原生還是模擬 clickEvent.forwardedTouchEvent = true; // 在目標(biāo)元素上觸發(fā)該鼠標(biāo)事件, targetElement.dispatchEvent(clickEvent);
我們?cè)诰W(wǎng)上搜索fastClick,大部分都在說(shuō)他解決了zepto的點(diǎn)擊穿透問(wèn)題,他是怎么解決的呢?就是上面最后一句,他模擬的click事件是在touchEnd獲取的真實(shí)元素上觸發(fā)的,而不是通過(guò)坐標(biāo)計(jì)算出來(lái)的元素。
最后,原理雖簡(jiǎn)單,但還是建議大家直接用FastClick而不是自己再實(shí)現(xiàn)一個(gè)。因?yàn)椋憧此创a里面的注釋,有很多特殊情況的補(bǔ)丁的,自己實(shí)現(xiàn)一個(gè)精簡(jiǎn)版難免會(huì)漏這漏那。
附錄同步發(fā)表于我的博客
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/85888.html
摘要:所有瀏覽器瀏覽器不支持安卓中中有屬性安卓中中有屬性有屬性的有屬性的所以在不需要的瀏覽器會(huì)直接掉,不會(huì)執(zhí)行下面的所有代碼。見(jiàn)源碼行,可以看出在響應(yīng)無(wú)操作后,則觸發(fā)。 其實(shí)一直就想花些時(shí)間讀一讀那些優(yōu)秀的開(kāi)源庫(kù),今天終于下了決定打算死磕下自己,2016年每個(gè)月讀2-3個(gè)優(yōu)秀的開(kāi)源庫(kù),把源碼精彩的地方和自己心得分享給大家。 目錄 (一)背景(二)源碼解析(三)Zepto 點(diǎn)擊穿透與 Fast...
摘要:移動(dòng)端經(jīng)常出現(xiàn)點(diǎn)透,至于怎么出現(xiàn)的請(qǐng)大家去看一下實(shí)現(xiàn)的源碼。點(diǎn)透是什么你可能碰到過(guò)在列表頁(yè)面上創(chuàng)建一個(gè)彈出層,彈出層有個(gè)關(guān)閉的按鈕,你點(diǎn)了這個(gè)按鈕關(guān)閉彈出層后后,這個(gè)按鈕正下方的內(nèi)容也會(huì)執(zhí)行點(diǎn)擊事件或打開(kāi)鏈接。這個(gè)被定義為這是一個(gè)點(diǎn)透現(xiàn)象。 移動(dòng)端經(jīng)常出現(xiàn)點(diǎn)透,至于怎么出現(xiàn)的請(qǐng)大家去看一下zepto實(shí)現(xiàn)tap的源碼。 1、點(diǎn)透是什么 你可能碰到過(guò)在列表頁(yè)面上創(chuàng)建一個(gè)彈出層,彈出層有個(gè)關(guān)...
摘要:移動(dòng)端經(jīng)常出現(xiàn)點(diǎn)透,至于怎么出現(xiàn)的請(qǐng)大家去看一下實(shí)現(xiàn)的源碼。點(diǎn)透是什么你可能碰到過(guò)在列表頁(yè)面上創(chuàng)建一個(gè)彈出層,彈出層有個(gè)關(guān)閉的按鈕,你點(diǎn)了這個(gè)按鈕關(guān)閉彈出層后后,這個(gè)按鈕正下方的內(nèi)容也會(huì)執(zhí)行點(diǎn)擊事件或打開(kāi)鏈接。這個(gè)被定義為這是一個(gè)點(diǎn)透現(xiàn)象。 移動(dòng)端經(jīng)常出現(xiàn)點(diǎn)透,至于怎么出現(xiàn)的請(qǐng)大家去看一下zepto實(shí)現(xiàn)tap的源碼。 1、點(diǎn)透是什么 你可能碰到過(guò)在列表頁(yè)面上創(chuàng)建一個(gè)彈出層,彈出層有個(gè)關(guān)...
閱讀 1107·2021-11-23 10:05
閱讀 1785·2021-11-12 10:36
閱讀 1853·2019-08-30 15:56
閱讀 1685·2019-08-29 12:32
閱讀 3043·2019-08-28 18:04
閱讀 3428·2019-08-26 12:17
閱讀 2502·2019-08-26 11:35
閱讀 1240·2019-08-23 15:11