移動頁面的點擊穿透問題

點擊穿透現象有3種:javascript

  • 點擊穿透問題:點擊蒙層(mask)上的關閉按鈕,蒙層消失後發現觸發了按鈕下面元素的click事件html

    蒙層的關閉按鈕綁定的是touch事件,而按鈕下面元素綁定的是click事件,touch事件觸發以後,蒙層消失了,300ms後這個點的click事件fire,event的target天然就是按鈕下面的元素,由於按鈕跟蒙層一塊兒消失了java

  • 跨頁面點擊穿透問題:若是按鈕下面剛好是一個有href屬性的a標籤,那麼頁面就會發生跳轉app

    由於 a標籤跳轉默認是click事件觸發 ,因此原理和上面的徹底相同測試

  • 另外一種跨頁面點擊穿透問題:此次沒有mask了,直接點擊頁內按鈕跳轉至新頁,而後發現新頁面中對應位置元素的click事件被觸發了spa

  • 和蒙層的道理同樣,js控制頁面跳轉的邏輯若是是綁定在touch事件上的,並且新頁面中對應位置的元素綁定的是click事件,並且頁面在300ms內完成了跳轉,三個條件同時知足,就出現這種狀況了.net

非要細分的話還有第四種,不過幾率很低,就是新頁面中對應位置元素剛好是a標籤,而後就發生連續跳轉了。。。諸如此類的,都是點擊穿透問題code

解決方案

問題已經很明瞭了,有不少解決方案,但思路不外乎2種:htm

  1. 不要混用touch和clickblog

    既然touch以後300ms會觸發click,只用touch或者只用click就天然不會存在問題了

  2. 吃掉(或者說是消費掉)touch以後的click

    依舊用tap,只是在可能發生點擊穿透的情形作額外的處理,拿個東西來擋住、或者tap後延遲350毫秒再隱藏mask、pointer-events、在下面元素的事件處理器裏作檢測(配合全局flag)等等,能吃掉就行

詳細解決方案

  1. 只用touch

    最簡單的解決方案,完美解決點擊穿透問題

    把頁面內全部click所有換成touch事件( touchstart 、’touchend’、’tap’),須要特別注意 a標籤,a標籤的href也是click,須要去掉換成js控制的跳轉,或者直接改爲span + tap控制跳轉。若是要求不高,不在意滑走或者滑進來觸發事件的話,span + touchend就能夠了,畢竟tap須要引入第三方庫

    不用a標籤其實沒什麼,移動app開發不用考慮SEO,即使用了a標籤,通常也會去掉全部默認樣式,不如直接用span

  2. 只用click

    下下策 ,由於會帶來300ms延遲,頁面內任何一個自定義交互都將增長300毫秒延遲,想一想都慢

    不用touch就不會存在touch以後300ms觸發click的問題,若是交互性要求不高能夠這麼作, 強烈不推薦 ,快一點老是好的

  3. 拿個東西來擋住

    比較笨的方法, 千萬不要用

    葉小釵的「菊花」大法,更多信息請查看 【移動端兼容問題研究】javascript事件機制詳解(涉及移動兼容)

  4. tap後延遲350ms再隱藏mask

    改動最小,缺點是隱藏mask變慢了,350ms仍是能感受到慢的

    只須要針對mask作處理就行,改動很是小,若是要求不高的話,用這個比較省力

  5. pointer-events

    比較麻煩且有缺陷, 不建議使用

    mask隱藏後,給按鈕下面元素添上 pointer-events: none; 樣式,讓click穿過去,350ms後去掉這個樣式,恢復響應

    缺陷是mask消失後的的350ms內,用戶能夠看到按鈕下面的元素點着沒反應,若是用戶手速很快的話必定會發現

  6. 在下面元素的事件處理器裏作檢測(配合全局flag)

    比較麻煩, 不建議使用

    全局flag記錄按鈕點擊的位置(座標點),在下面元素的事件處理器裏判斷event的座標點,若是相同則是那個可惡的click,拒絕響應

    上面說的只是想法,沒測試過,實在不行就用記錄時間戳判斷,等待350ms,這樣就和 pointer-events 差很少

  7. fastclick

    好用的解決方案,不介意多加載幾KB的話, 不建議使用 ,由於有人遇到了bug,更多信息請查看: Fastclick 致使click事件觸發兩次的問題

    首先引入fastclick庫,再把頁面內全部touch事件都換成click,其實稍微有點麻煩,建議引入這幾KB就爲了解決點透問題不值得,不如用第一種方法呢

相關文章
相關標籤/搜索