开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 1 天,点击查看活动详情
需求
动态吸顶
传送门,欢迎star。
最终效果:
tips:本次实现没有使用 sticky属性。 position:sticky简单粗暴,但存在部分机型不支持.
方式一
通过设置样式fixed
页面布局的时候,通过view占位
<view class="navbar-wrap" id="navbar-wrap">
<view class="column {{isFixedTop?'fixed':''}}" id="navbar" bindtap="handleNavbar">
<view class="tab">兔年大吉</view>
<view class="tab">身体健康</view>
<view class="tab">阖家幸福</view>
<view class="tab">财源滚滚</view>
</view>
<!-- 用于吸顶后 占位用的 -->
<view class="column" wx:if="{{isFixedTop}}"></view>
<view class="back-top" wx:if="{{isFixedTop}}" bindtap="handleTop">顶部</view>
</view>
在页面加载的时候,测量出navbar距离顶部的距离top。
var query = wx.createSelectorQuery();
query.select('#navbar').boundingClientRect((res) => {
wx.setStorageSync('navbar', res?.top)
}).exec()
在页面滑动的时候,计算滚动条距离顶部高度 与navbar的距离。如果scrollTop的距离大于navbar距离底部的距离那么固定,防止不固定。
if (scrollTop > top) {
this.setData({
isFixedTop: true
});
} else {
this.setData({
isFixedTop: false
});
}
场景一的效果图
优化
之前在onPageScroll中进行了一些逻辑判断,并且重新渲染界面setData方法。如果不停的刷新界面,有可能会导致界面卡顿,不流程。控制 setData 的频率,避免不停的去setData。
let isSatisfy = scrollTop >= top ? true : false;
//为了防止不停的setData, 这儿做了一个等式判断。 只有处于吸顶的临界值才会不相等
if (this.data.isFixedTop === isSatisfy) {
return false;
}
this.setData({
isFixedTop: isSatisfy
});
小程序中使用setData的建议,详情见微信官方api。
- data 应只包括渲染相关的数据
- 控制 setData 的频率
- 选择合适的 setData 范围
- setData 应只传发生变化的数据
优化后的效果图
方式二
随着业务的扩展,比如某一功能模块的数据无时,不展示。或者增加一些功能模块。
思路一:
根据业务逻辑,列举枚举中不同功能模块隐藏后。动态的增删 navbar距离顶部的高度。缺点:业务可能会不统一,距离高度需要按照比例测量。
思路二:
根据业务逻辑,数据响应后。重新计算navbar距离顶部的距离。缺点:网络请求后都需要重新计算,即使搭配使用promise.all方法也不能完全保证页面渲染时机。或者通过setData渲染完成后。
思路三: 通过类似参照线的方式,动态计算距离顶部高度的距离。
var query = wx.createSelectorQuery();
query.select('#navbar-wrap').boundingClientRect((res) => {
let top = parseInt(res?.top)
// 距离顶部的高度
let isSatisfy = (top < 0) ? true : false;
if (this.data.isFixedTop !== isSatisfy) {
this.setData({
isFixedTop: isSatisfy
})
}
}).exec()
场景二的效果图
优化
页面滚动onPageScroll存在了大量了计算逻辑,可能会存在卡顿。这里使用节流函数throttle
在onPageScroll中去动态判断当前距离顶部高度的状态。
总结
- 动态计算高度
- 控制刷新频率,防止页面卡顿
- 合理使用setData