1. 程式人生 > >【相容性】ios上設定overflow: scroll不滾動bug

【相容性】ios上設定overflow: scroll不滾動bug

背景

目前遇到這麼一個問題:我有一個可以向下展開的下來選單,選單初始高度大於300px左右,沒有超過手機螢幕高度,當展開的時候如果超過手機螢幕高度時讓父元素出現滾動條滾動,就是說內容的高度是動態的。

描述

此前我通過js動態獲取螢幕高度,並設定為父元素的max-height。然後設定父元素overflow-y: scroll;

起初,我大概的程式碼佈局如下:

 <div className='' style={{ maxHeight: this.state.viewPortHeihgt + "px" }}>
     <Lists>
       .
       .
       .
     </
Lists
>
</div>

其中Lists中的內容的高度是動態的。
css如下:

 .small-nav{
     overflow-y: scroll;
     overflow-x: hidden;
   }

此方法在andriod和pc上執行正常,但是在ios上就出現卡出不能滑動的現象。

分析

我們知道,頁面的渲染流程分為以下幾個步驟:

  1. 構建DOM tree
  2. 構建CSS Rule tree
  3. 根據DOM tree和CSS tree來構建render tree
  4. 根據render tree計算頁面的layout
  5. render頁面

safari瀏覽器在構建render tree的時候,會預先找到相應的overflow: scroll元素,在計算頁面layout的時候,會計算父元素的高度與子元素的高度,若子元素高於父元素,則在render頁面時為其建立一個原生的scrollView。當子元素的高度小於父元素的高度時,safari不會給父元素一個原生的scrollView。

這裡我Lists中的內容初始是小於父元素.small-nav的高度的,所以在ios的解釋中不會給父元素新增一個scrollView。

解決

針對這種情況,我們可以設定讓瀏覽器一開始就給父元素增加scrollView,當我們的內容撐開,高過父元素的時候,就可以進行滑動。

程式碼如下:

 <div className='small-nav-outer' style={{ height: this.state.viewPortHeihgt + "px" }}>
   <div className='small-nav-inner'>
     <Lists>
       .
       .
       .
     </
Lists
>
</div> </div>
.small-nav-outer{
  -webkit-overflow-scrolling: touch;
   overflow-y: scroll;
   overflow-x: hidden;
 }
 .small-nav-inner{
   min-height: calc(100% + 1px);
 }

程式碼中可以看出,我在父元素的內部新增一個一個包裹的div,.small-nav-inner,讓他的高度高於父元素1px,然後給父元素新增 -webkit-overflow-scrolling: touch;屬性,這樣可以令一開始的時候就新增一個scrollView。

如此,ios上的相容性問題得以解決。