先放個圖看看滑動固頂是啥效果:javascript
中間那個 tab 條,日常的時候是固定的,等到頁面滑上去的時候,又像 fixed 同樣貼在頂部。
position: sticky 就是用來實現這個效果的,元素不脫離文檔流,仍然保留高度,因此這個屬性真是人畜無害啊,並且效果如絲般潤滑,堪比原生。css
事實上,不少看起來人畜無害的東西,其背後都有一個大坑。html
咱們的 html 結構是這樣的:java
<body ontouchstart="">
<div class="page-wrapper">
<div id="contentA" class="content-a">
A
</div>
<div class="sticky-wrap ">
<ul class="ui-tab-nav ui-border-b frown ">
<li class="current">推薦</li>
<li>分類</li>
</ul>
</div>
<div id="contentB" class="content-b">
B
</div>
</div>
</body>複製代碼
主要的 css 以下:android
.sticky-wrap {
top: 0;
width: 100%;
z-index: 999;
}
.sticky-wrap {
position: relative;
position: -webkit-sticky;
}
.page-wrapper.sticky .sticky-wrap {
position: fixed;
}
.content-a {
height: 200px;
background-color: #12b7f5;
color: #fff;
font-size: 48px;
text-align: center;
line-height: 200px;
}
.content-b {
height: 800px;
font-size: 48px;
text-align: center;
line-height: 200px;
}複製代碼
這裏須要注意幾點,這裏 sticky-wrap
是咱們設置了position: -webkit-sticky;
的元素,這個元素的位置比較重要,不是隨便放哪均可以實現那個效果的,sticky 效果是按照父元素的高度來的,若是你的父元素高度很小,會出現滑完父元素就再也不固頂的奇怪狀況。git
而後咱們設置了 top 值,sticky 的元素必須有 top 或者 bottom 屬性,否則不會生效。程序員
除了一些要設置的東西以外,還有一個不能設置的東西。 sticky 元素的父元素或者祖先元素不能含有 overflow:hidden
或者 overflow:auto
。github
基本上小坑就這些,還有一個大坑叫作『只有 iOS 支持這個屬性』。web
這裏咱們不得不借助 js 和 positon:fixed
。設計模式
添加一段 js:
var isStopTimer = null;
var offsetTop = $('.content-a').offset().height;
//置頂效果
if ($('.sticky-wrap').css("position").indexOf("-webkit-sticky") == -1) {
$('.page-wrapper').on('touchend', function() {
clearInterval(isStopTimer);
isStopTimer = setInterval(function() {
document.body.scrollTop >= offsetTop ? $('.page-wrapper').addClass('sticky') : $('.page-wrapper').removeClass('sticky');
}, 200)
});
$('.page-wrapper').on('touchmove', function() {
document.body.scrollTop >= offsetTop ? $('.page-wrapper').addClass('sticky') : $('.page-wrapper').removeClass('sticky');
});
}複製代碼
這裏經過計算 $('.sticky-wrap').css("position").indexOf("-webkit-sticky")
是否有效來判斷瀏覽器是否支持 sticky 屬性,而後經過監聽 touchmove 和 touchend 事件,在合適的時候添加一個叫 sticky
的類,這個類設置帶了些樣式:
.page-wrapper.sticky .sticky-wrap {
position: fixed;
}複製代碼
在須要固頂的時候咱們將元素的 positon 改成 fixed
,可是這裏又有個坑,設置元素爲 fixed 的時候,相應元素是脫離文檔流的,也就是沒有高度了,仔細看滑動的時候,底下的元素有一個跳動。
爲了解決這個跳動,咱們可讓本來在下面那個元素加點高度,而後和 sticky 元素重合,爲了之後改動頁面的時候不影響這個邏輯,用 js 去算高度會比較好。
加入以下代碼:
var tabContentTop = $('.ui-tab-nav').offset().height;
var orgPaddingTop = parseInt($('.content-b').css('padding-top'));
$('.content-b').css('padding-top', tabContentTop+orgPaddingTop);
$('.sticky-wrap').css('margin-bottom', -tabContentTop);複製代碼
這裏用 padding-top 來給 content-b 增長高度,給 sticky-wrap 添加負的 margin-bottom 值來讓 content-b 上來和 sticky-wrap 重合。未免覆蓋原來 content-b 的 padding-top 值,最好獲取一下再加,記得用 parseInt
轉一下。
到這裏基本坑都踩完了,雖然 Android 效果沒有 iOS 那麼絲滑舒服,也勉強能接受了。
最後說下調試 sticky 效果,既然是 iOS 才支持的東西,首先你要有 safari,可是日常打開是沒用的,要在開發菜單那裏選擇 進入響應式設計模式
很久沒發文章了,最近實在太忙,不知道是否是加班多了,還生病了,身體是革命的本錢啊,2017 祝你們身體健康。
記錄一些所思所想,寫寫科技與人文,寫寫生活狀態,寫寫讀書感悟,主要是扯淡和感悟,歡迎關注,交流。
微信公衆號:程序員的詩和遠方
公衆號ID : MonkeyCoder-Life