移動頁面點擊穿透問題解決方案

來源:互聯網
上載者:User

標籤:

移動頁面點擊穿透問題解決方案時間 2015-08-24 21:43:58  黯羽輕揚原文  http://www.ayqy.net/blog/移動頁面點擊穿透問題解決方案/主題 JavaScript一.click與300ms延遲

行動瀏覽器提供一個特殊的功能:雙擊(double tap)放大

300ms的延遲就來自這裡,使用者碰觸頁面之後,需要等待一段時間來判斷是不是雙擊(double tap)動作,而不是立即響應單擊(click),等待的這段時間大約是300ms。之前有過簡單介紹: 黯羽輕揚:HTML5觸摸事件

移動事件提供了 touchstart 、 touchmove 、 touchend 卻沒有提供tap支援,主流架構(庫)都是手動實現了自訂tap事件,以求消除300ms延遲,提高頁面響應速度。對於簡單的頁面,可以把 touchstart 或者 touchend 當作tap來用,但存在一些問題,比如手指接觸目標元素,按住不放,慢慢移出響應地區,會觸發touchstart 事件執行對應的事件處理器(本不應該觸發), touchend 事件也存在類似的問題。

此外, 使用原生touch事件也存在點擊穿透的問題 ,因為click是在touch系列事件發生後大約300ms才觸發的,混用touch和click肯定會導致點透問題,下面詳細介紹

二.點擊穿透問題

點擊穿透現象有3種:

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

    蒙層的關閉按鈕綁定的是touch事件,而按鈕下面元素繫結的是click事件,touch事件觸發之後,蒙層消失了,300ms後這個點的click事件fire,event的target自然就是按鈕下面的元素,因為按鈕跟蒙層一起消失了

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

    因為 a標籤跳轉預設是click事件觸發 ,所以原理和上面的完全相同

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

    和蒙層的道理一樣,js控制頁面跳轉的邏輯如果是綁定在touch事件上的,而且新頁面中對應位置的元素繫結的是click事件,而且頁面在300ms內完成了跳轉,三個條件同時滿足,就出現這種情況了

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

三.解決方案

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

  1. 不要混用touch和click

    既然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就為瞭解決點透問題不值得,不如用第一種方法呢

四.DEMO

寫了不少測試頁面,請查看: [email protected] ayqy / my.js

參考資料
  • 前輩博文若干

移動頁面點擊穿透問題解決方案

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.