說說移動端web開發中的點擊穿透問題


最近一直在忙於一個無線端的項目,由於之前主要工作都是在桌面端,移動端接觸的比較少,所以中間遇到了很多的坑,做一個簡單的記錄。

問題背景

需求中有這樣的一個功能,點擊取件信息的時候會彈出一個地址列表的浮層,用戶選擇地址之后會將具體的地址回填到取件信息當中去。按道理講,這是一個非常簡單的功能,可是在開發過程中卻遇到了很多非常詭異的事情。

初始的代碼是這么寫的:

var pickupInfo = $("#pickupInfo");  
pickupInfo.on("tap", function () {
    var addressList = $("#addressList");
    addressList.show();
});  

window.addEventListener("message", function () {
    // 回填地址信息
});
// addressList 是一個浮層
$("#addressList li").on("click", function () {
	// 此處回填地址到取件信息中去  
	// 具體方式則是通過iframe的postMessage發送消息,pickupInfo那邊接收消息后填充
});

為了更清楚的說明問題,此處刪除了很多的業務邏輯。

在測試過程中就發現了一個詭異的問題,在點擊pickupInfo的時候,addressList浮層閃了一下就消失了,彈出addressList浮層后立即回填了地址信息。

因為一開始也沒有太注意觀察,跟代碼的過程中發現只要浮層一彈出,pickupInfo那邊就立即收到了message事件信息。當時第一反應感覺是地址列表那邊出了問題,看了好幾遍代碼,一直沒發現哪里有問題,也跟了幾次,每次都是地址列表一彈出就立即觸發了click事件。

奇了個怪了!

點擊穿透

試着描述了下問題google了一把,可能是描述的不太准確,啥也沒搜着。沒辦法了,瞪大眼睛再操作一遍。這時候奇跡出現了,我發現每次點擊pickupInfo,都在選中addressList中相對於屏幕與pickupInfo相同位置的地址。

查看了下事發地點的代碼,然后在google中敲下了這幾個字“移動端 tap”,一大堆的結果,看了幾篇文章,終於找到了問題的答案。

先說說touch事件吧。

我們知道,PC上有鼠標事件,一次點擊可以拆分成mousedown > click > mouseup 三步。移動端沒有鼠標,但是有類似的觸摸事件,用戶的一次點擊可以分為touchstart > touchmove > touchend。 雖然手機上沒有mouse事件,但是手機依然可以響應mouse事件,為什么呢?是通過touch事件來模擬的。有人曾經對比測試過手機上和PC上的mouse事件,發現手機上的mouse要慢一些,大概在300m左右。

再說說tap事件。

在PC端,我們經常使用到click事件,對應到移動端,我們使用tap事件。但原生的touch事件本身是沒有tap的,也是通過模擬產生的。在Zepto中,如果在touchend事件響應250ms無操作后,會觸發singleTap事件。

// trigger single tap after 250ms of inactivity
else {
    touchTimeout = setTimeout(function(){
        touchTimeout = null
        if (touch.el) touch.el.trigger('singleTap')
        touch = {}
    }, 250)
} 

至此,點擊穿透的原因就明了了。

當pickupInfo監聽的tap事件得到響應之后,會立即彈出addressList浮層,此時瀏覽器還會觸發click事件,而此時原來的pickupInfo已經完全被addressList遮罩,所以click事件就被觸發在了與pickupInfo相同位置的addressList中對應的區域,也就正好響應了addressList中監聽的click事件。

世事奈何如此之巧~

解決方案

問題清楚了,修改方法也就明確了,由於項目還在開發中,個人覺得當前的方案還不是特別好,后續優化后再貼出來。這里貼篇文章,也來說說touch事件與點擊穿透問題,里面對touch和tap事件做了詳細的說明,對點擊穿透問題也提到了幾個方案,可以參考。

小結

這兩天一直在忙於趕開發進度,對於過程中遇到的一些典型的問題做一些記錄,算是一種沉淀吧~~


免責聲明!

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



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