小程序实战(十四)-筛选菜单吸顶

3,729 阅读2分钟

一、需求说明

  1. 列表页面中部有一个筛选菜单
  2. 当向上滑动时,刚开始菜单跟着滑动,当菜单到达顶部时固定在顶部不再滑动

二、需求实现

2.1 整体思路

这个需求的整体思路是:

  1. 通过动态 class 来实现菜单的不同布局状态
  2. 获取元素,拿到菜单距离顶部的距离
  3. 在滚动事件中判断,当滚动距离大于菜单距离顶部的距离,就增加 class

2.2 获取菜单距离顶部距离

html 结构

<view>导航栏</view>
<view id="menu">菜单栏</view>
<view>内容区</view>
let that = this
let query = wx.createSelectorQuery()
query.select('#menu').boundingClientRect()
query.exec(function(res) {
 that.setData({
  menuTop: res[0].top         // 获取距离顶部的距离
 })
})

2.3 滚动时判断距离

<view>导航栏</view>
<view id="menu" class="{{menuFixed ? 'menu-fixed' : ''}}">菜单栏</view>
<view>内容区</view>
onPageScroll(e) {
 this.setData({
  menuFixed: (e.scrollTop > this.data.menuTop)
 })
}

2.4 固定后菜单的样式

.menu-fixed{
 position: fixed;
}

三、出现的坑

3.1 菜单上面有元素需要通过调用接口渲染

若存在这种情况,需要在接口返回数据后,再计算菜单到顶部的距离。防止由于元素未渲染而引起距离计算错误:

onLoad() {
 post(api.getTypes).then(res => {
  // 已获取到数据
  this.getMenuTop()
 })
},
getMenuTop() {
 let that = this
 let query = wx.createSelectorQuery()
 query.select('#menu').boundingClientRect()
 query.exec(function(res) {
  that.setData({
   menuTop: res[0].top         // 获取至顶部的距离
  })
 })
}

3.2 菜单上有图片

若菜单上部有图片,需要注意原图的尺寸,在渲染时,会先按原图尺寸渲染,后再按照图片容器设定的大小渲染。 若原图尺寸大,会造成计算距离时,菜单至顶部距离偏大。

3.3 时不时的卡顿感

onPageScroll 这个函数被调用非常频繁,如果直接在里面写 setData 语句,会造成不间断地赋值,影响性能。 这个地方需要做优化,比如:

onPageScroll(e) {
 if (this.data.menuFiXed === (e.scrollTop > this.data.menuTop)) return
 this.setData({
  menuFixed: (e.scrollTop > this.data.menuTop)
 })
}

当滚动距离大于菜单距离后,会将 menuFixed 赋值为 true,在这之后,若继续向下滚动,会继续调用这个函数。这时判断若结果相等,就直接 return ,阻止多次的 setData 操作。

<关于我们>

我们是来自帝都的一枚前端程序猿 + 一枚前端程序媛。

这里发布的文章是我们对学习内容的总结,预计会每周至少会更新一篇。

目前我们学习计划是: 小程序实战 => vue 进阶用法 => vue 原理 => css 基础 => es6 => js 深入

另外,工作中用到的一些技术和完成的功能,我们也会及时总结更新在这里

如文章有错误或表述不清晰,欢迎各位留言反馈~~