touch-action導致安卓頁面無法滾動

前言

相信大家搜css touch-action很容易搜到一批文章,但感覺自己還是需要寫下自己這這個過程中的一些探索經歷。

之所以寫,是因爲單獨去學知識點或者單獨看一篇文章其實很簡單的,難的是在自己實踐中,因爲一個問題找一個方案,然後又引起另外一個問題,而這個不斷髮現問題的過程非常低效,需要各種嘗試和理解。

使用css touch-action的原因

在其官方的說明中:是否,以及以何種方式,給定的區域,可以由用戶通過觸摸屏操作(例如,通過平移或縮放內置的瀏覽器功能)

但我最初並不是因爲這個來使用它的,後續會補充一篇使用這個特性做出來的效果。我用這個屬性是因爲自己在使用antd-mobile的走馬燈時候,在控制檯代碼警告,內容是這樣的:

[Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive. See…

看到這樣的報錯,作爲程序員,職業病肯定是要查看原因的,雖然不影響正常使用。經過查閱,其簡單的描述就是這樣的:Passive event listeners,做了移動端的優化。看完一臉懵逼。其實就是是否阻止默認事件200ms延遲然後再執行滾動行爲,而之前的fastclick就是通過去掉這部分來避免點擊延遲的。

For instance, in Chrome for Android 80% of the touch events that block
scrolling never actually prevent it. 10% of these events add more than
100ms of delay to the start of scrolling, and a catastrophic delay of
at least 500ms occurs in 1% of scrolls.

想知道更多,可以參考這篇,寫的比較詳細了: 移動Web滾動性能優化: Passive event listeners

然後知道原因不夠,解決方案是什麼?

能搜到的方案是兩種,一種是通過css方式,一種是通過js的方式。 css方式:比較簡單

touch-action:none 

js方式:在touch的事件監聽方法上綁定第三個參數{ passive: false }

elem.addEventListener(
  'touchstart',
  fn,
  { passive: false }
);

使用touch-action之後,問題來了

然後當然是開心的用第一種方案把這行css寫到全局中,結果就帶來了災難。 什麼問題呢?就是ios基本都可以的,但是安卓中的頁面滾動都沒了。這是爲什麼呢?這個就要看下touch-action的更官方的觸摸說明了。

默認情況下,平移(滾動)和捏手勢由瀏覽器獨佔處理。當瀏覽器開始處理觸摸手勢時,使用的應用程序Pointer_events將收到一個pointercancel事件。 通過明確指定瀏覽器應該處理哪些手勢,應用程序可以爲其餘手勢提供自己的行爲,pointermove並pointerup爲其餘的手勢提供監聽器。應用程序使用Touch_events。 通過調用禁用瀏覽器處理手勢preventDefault(),但也應該使用觸摸動作來確保瀏覽器在調用任何事件偵聽器之前知道應用程序的意圖。當手勢開始時,瀏覽器將觸摸元素及其所有祖先的觸摸動作值與實現手勢的觸摸動作值(換句話說,第一個包含滾動元素)相交。 這意味着在實踐中,觸摸動作通常只應用於具有一些自定義行爲的單個元素,而不需要在該元素的任何後代上明確指定觸摸動作。手勢開始後,觸摸動作值的更改將不會對當前手勢的行爲產生任何影響。

文檔參考來源:touch-action

說人話

這段話闡明的就是觸摸事件整個的進行過程,既然它可以通過css來約定滾動的行爲,那麼就意味着你寫了touch-action:none,就會導致原來的頁面滾動失效了。這就是安卓上無法頁面滾動的原因。

爲什麼ios沒有受影響呢,我覺得可能是ios默認支持touch事件的原因吧。如果你知道底層的原因或者詳細的文檔說明,可以告訴我哦。

怎麼解決呢

先臨時把對應的touch:none,全局的寫法去掉了,用了js的部分去完成或者只在控制需要的元素內進行指定這行代碼。由此也總結了幾個問題或者教訓吧。 – 在寫全局樣式的要注意影響範圍 – 在每次提交代碼的時候儘可能針對不確定的部分增加備註,風險埋點,因爲這次剛好是因爲用戶有反饋這個問題,我想到了是加了這行代碼的原因,但如果是其他時候或者過了很久,其實很難定位到是因爲這行代碼的原因。我遇到這個問題的時候,第一感覺還是是否是腳本錯誤了,是否是兼容問題。如果是這樣排查的話,就會浪費比較多的時間。甚至中間還找羣友討論,他們建議是否更換爲絕對定位的方案,那樣就真走偏了。 – 問題拿到後的冷靜分析,拿到這個問題不要過於着急,還是要分析下產生問題的原因,尤其是機型,因爲我們之前做測試都是模擬器和蘋果的ios,而這次報問題的都是安卓的機型,而且是小米56,堅果,華爲等。聯想到這些安卓機型,那麼定位到可能是 :代碼兼容部分的版本過低,這些不支持;代碼某部分是對ios和安卓有區分解釋的,和系統有關,版本無關。

更多延伸與拓展

通過touch-action可以做什麼效果呢? – 禁止默認的滾動touch-action:none – 可以控制用戶行爲的處理細節,比如只接受x或者y方向的變化,來影響行爲,確定行爲邊界 – 優化用戶多次點擊造成界面所放 – 更多等待你的發掘

更多

說明:如果你想更好的使用滾動相關的體驗,還是入手框架吧,不然坑太多,iscroll,better-scroll(一般滾動組件依賴的庫).me-scroll(個人推薦)都是不錯的選擇 – 安利一篇還不錯的採坑文章: 深入研究-webkit-overflow-scrolling

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章