移動端實現滾動的四種方案


如果在一個區域內只允許部分區域產生滾動的效果,而其余部分不能移動,你會采用什么方法呢?

首先我們可以把這個需求分解為兩個小的問題來解決。

  • 部分區域固定
  • 其余區域滾動

部分區域固定

  1. 為頁面的body部分設置height: 100%以及overflow: hidden,即禁用頁面原生的滾動,保證只會顯示一屏的內容。
  2. 固定區域采用絕對定位。

其余區域滾動

核心屬性overflow-y

mdn對於overflow-y的定義
The overflow-y property specifies whether to clip content, render a scroll bar, or display overflow content of a block-level element, when it overflows at the top and bottom edges.
overflow-y屬性指定或是裁剪內容並且渲染一個滾動條,或是當塊級元素在其頂部或底部溢出時顯示溢出的內容。

簡單來說,overflow-y屬性在垂直方向上存在溢出的時候,通過設置不同的值會產生不同的表現。為了實現滾動功能我們需要將該屬性設置為scroll,之后,無論塊級元素的內容是否溢出,瀏覽器都會生成一個滾動條並且隱藏容器中內容溢出的部分,只有在滾動之后才會顯示。

舉個例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.test{
width: 200px;
/* 關鍵樣式 */
height: 200px;
overflow-y: scroll;
/* 以下無關樣式 */
background: #f14c5c;
color: #fff;
}
< div class="test">
這里面只是一段測試的內容這里面只是一段測試的內容這里面只是一段測試的內容
這里面只是一段測試的內容這里面只是一段測試的內容這里面只是一段測試的內容
這里面只是一段測試的內容這里面只是一段測試的內容這里面只是一段測試的內容
這里面只是一段測試的內容這里面只是一段測試的內容這里面只是一段測試的內容
</div>

效果如下:


這里面只是一段測試的內容這里面只是一段測試的內容這里面只是一段測試的內容這里面只是一段測試的內容這里面只是一段測試的內容這里面只是一段測試的內容這里面只是一段測試的內容這里面只是一段測試的內容這里面只是一段測試的內容這里面只是一段測試的內容這里面只是一段測試的內容這里面只是一段測試的內容

通過剛才的例子我們可以得出結論,只要限制塊級元素的高度,自然就可以實現只有該元素的內容可滾動而不影響其它內容。但是在實現過程中遇到了新的問題,如何實現對設計圖的精確還原?設計圖如下:

設計圖

整個彈出框高度是隨頁面高度自適應的,標題部分和底部按鈕部分位置是固定的,中間列表需要占滿剩余高度,並且內容可滾動。整個彈窗被最外層div包裹,底部按鈕相對於它進行定位。經過思考后,嘗試了四種方案,分享給大家。

方案說明

我們需要確定的核心問題就是中間內容的高度,也即是height在不同尺寸屏幕下的精確高度。

vh

相對於視口的高度,視口被均分為100單位,即1vh等於視口高度的1%。

vh-caniuse

但是vh單位對低版本安卓和ios支持不夠好,微信瀏覽器X5內核不支持,雖然已經升級到blink內核,但是為了確保萬無一失,放棄采用這種方案。另外也無法精確控制和底部按鈕邊距。

height百分比

和vh類似,無法精確控制和底部按鈕的邊距,自適應效果不好。

calc

對於以上兩種方案的存在的問題,calc計算屬性可以很好的解決,只需要設置height:calc(100% - 60px),就可以精准的占滿中間部分,並且保持和底部按鈕的邊距。

calc-caniuse

可惜的是對於低版本的安卓瀏覽器、ios瀏覽器包括微信瀏覽器在內的主流瀏覽器支持都不好,依然只能棄用。
如果兼容性再好一點的話,calc方案應該是最好用且最優雅的一種實現方式。

js

單純的使用css無法實現,就只能借助js來動態計算內容所需要的高度來進行設置。同時這種方法也幾乎不會遇到兼容性的問題,是對優雅降級的一種實踐。

題外話

隱藏難看的滾動條。

scrollbar
如果直接設置overflow-y:scroll在ios下始終會出現很丑的滾動條,我們可以對該元素設置以下屬性:

1
2
margin-right: -20px;
padding-right: 20px;

對滾動條進行一個小小的hack,它就再也不會出現了,用戶交互時會有和原生滾動一樣的感覺,體驗更佳。

@prototype 經大大提醒,設置webkit瀏覽器的私有屬性::-webkit-scrollbar能更靈活的控制滾動條,在此感謝。如果只需要隱藏,如下代碼即可:

1
2
3
::-webkit-scrollbar{
display: none
}

雖然移動端的瀏覽器webkit內核居多,不過還是要在真機測試后再得出結論,如果有些瀏覽器不支持這個屬性的話,依然可以使用上面的小hack。

-webkit-overflow-scrolling: touch

在ios設備中,利用overflow來模擬滾動會出現卡頓的情況,可以通過設置-webkit-overflow-scrolling: touch來解決,原因是設置后ios會為其創建一個UIScrollView,利用硬件來加速渲染。

這個問題本身並不復雜,甚至需求更改后,實現變的非常簡單。但是希望能通過這個小例子能讓每一個前端人在思考需求時都能夠盡可能的去想更多樣的方法來解決問題,即使因為兼容性或其它原因暫時無法實現,在這個過程中獲得的成長也是非常有益的。

 
原文鏈接:移動端實現內滾動的4種方案

 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM