博客 / 詳情

返回

h5 兼容性-ios 滾動問題及可能的方

滾動事件

addEventListener 使用 passive 改善的滾屏性能

根據規範,passive 選項的默認值始終為false。但是,這引入了處理某些觸摸事件(以及其他)的事件監聽器在嘗試處理滾動時阻止瀏覽器的主線程的可能性,從而導致滾動處理期間性能可能大大降低。

為防止出現此問題,某些瀏覽器(特別是Chrome和Firefox)已將文檔級節點 Window,Document和Document.body的touchstart (en-US)和touchmove (en-US)事件的passive選項的默認值更改為true。這可以防止調用事件監聽器,因此在用户滾動時無法阻止頁面呈現。


var elem = document.getElementById('elem');
elem.addEventListener('touchmove', function listener() { /* do something */ }, { passive: true });
Copy to Clipboard

添加passive參數後,touchmove事件不會阻塞頁面的滾動(同樣適用於鼠標的滾輪事件)
您可以通過將passive的值顯式設置為false來覆蓋此行為,如下所示:


/* Feature detection */
/*特徵檢測*/
var passiveIfSupported = false;

try {
  window.addEventListener("test", null, Object.defineProperty({}, "passive", { get: function() { passiveIfSupported = { passive: true }; } }));
} catch(err) {}

window.addEventListener('scroll', function(event) {
  /* do something */
  // can't use event.preventDefault();
  // 不能使用 event.preventDefault()
}, passiveIfSupported );

在不支持addEventListener()的options參數的舊瀏覽器上,嘗試使用它會阻止使用useCapture參數而不正確使用特徵檢測。

您無需擔心基本scroll (en-US) 事件的passive值。由於無法取消,因此事件監聽器無法阻止頁面呈現。

問題-ios滾動卡頓不流暢?

解決方案

  1. body、局部滾動容器添加 -webkit-overflow-scrolling:touch

 -webkit-overflow-scrolling

auto:使用普通滾動, 當手指從觸摸屏上移開,滾動會立即停止。
touch: 使用具有回彈效果的滾動,當手指從觸摸屏上移開,內容會繼續保持一段時間的滾動效果。繼續滾動的速度和持續的時間和滾動手勢的強烈程度成正比。同時也會創建一個新的堆棧上下文。
在移動端上,在你用overflow-y:scroll屬性的時候,你會發現滾動的效果很很生硬,很慢,這時候可以使用-webkit-overflow-scrolling:touch這個屬性,讓滾動條產生滾動回彈的效果,就像ios原生的滾動條一樣流暢。

問題-ios偶現滾動時最底部的內容被固定的tab菜單欄遮擋

嘗試解決方案

  1. 父級元素的滾動容器添加 -webkit-overflow-scrolling:touch (未復現),但是這種方案, ios(13.1.3)最外層會默認出現滾動條,如不需出現滾動條的,需手動在最外層添加隱藏滾動條的樣式
-webkit-scrollbar {
   display: none;
}
  1. 父級元素的底部添加paddingBottom,外層默認會增多一部分空白,不友好

問題-ios滾動到指定位置,出現部分組件渲染空白,滾動後正常顯示,或滾動後部分元素渲染被截斷

ios 11(13.1.3),當頁面點擊頂部的關鍵字或底部輸入框輸入關鍵字時,可出現查詢的結果卡片,多次查詢後,從頂部點擊關鍵字直接滾動到最新的結果卡片時,結果卡片出現渲染異常(部分/全部元素渲染不出),來回滾動後,元素出現。

嘗試解決方案

  1. 滾動到底部位置時,加一個定時器 (復現)
  2. 取消父級元素的overflow:hidden (復現)
  3. 強制渲染子元素的內容 (復現)
  4. 父級元素的滾動容器添加 -webkit-overflow-scrolling:touch (復現)
  5. 添加wil-change:scroll-position (復現)
  6. 父級元素及子元素添加最小高度 (復現,出現頻率降低)
  7. 父元素滾動前設置-webkit-overflow-scrolling:touch, 滾動結束後設置-webkit-overflow-scrolling:touch (同一種組件未出現,2種組件交替出現時復現、無效)
  8. 父元素設置backface-visibility: hidden;transform: translate3d(0,0,0); (復現)
  9. 父元素取消z-index設置,同時添加-webkit-overflow-scrolling:auto; (同一種組件或不同種組件交替出現時,均不再出現)

    小結

    -webkit-overflow-scrolling:touch這個屬性添加後可能會引起一些奇奇怪怪的bug,上述是可能是由於層級z-index的設置或者是組件元素的不一致(試過用同一種組件,但是取消了單個結果的輪播點切換,復現),導致在視覺上渲染被遮擋的問題。
    上述的幾種情況是依據當時bug復現不同的表現而排查的步驟,最終還是得根據不同情況來修復問題。

問題-ios容器列表初始不能上滑加載更多數據,需下拉刷新後才能觸發上滑加載更多

當設置了overflow-y:auto的滾動容器高度減少一定的像素時,復現該問題, 但是要注意減少的容器高度,不然會引起最後一個列表元素的部分內容被遮擋。

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.