实现锚点定位和滚动监听功能
- [1. 思路解析](#1. 思路解析)
- [2. 代码示例](#2. 代码示例)
效果截图示例:
- 点击左侧menu,右侧列表数据实现锚点定位
1. 思路解析
- 点击左侧按钮,更新右侧
scroll-view
对应的scroll-into-view
的值,即可实现右侧锚点定位 - 滚动右侧区域,计算右侧滚动距离 动态更新左侧
scroll-view
对应的scroll-into-view
的值,即可实现左侧锚点定位(暂无需求,先提供思路)
2. 代码示例
HTML
html
<view>
<!-- 左侧menu -->
<scroll-view scroll-y="true" :scroll-into-view="category.categoryMenuIntoView"
scroll-with-animation="true">
<view :id='"category-menu-" + index' v-for="(item, index) in category.coffeeList" :key="item.categoryId" @click="switchCategoryMenu(item,index)">
{{ item.categoryName }}
</view>
</scroll-view>
<!-- 右侧列表 -->
<scroll-view scroll-y="true" :scroll-into-view="category.coffeeIntoView" scroll-with-animation="true">
<view :id='"category-coffee-" + index' @scroll='coffeeScroll'>
{{item.name}}
</view>
</scroll-view>
</view>
重点:
scroll-into-view
:值应为某子元素id(id不能以数字开头)。设置哪个方向可滚动,则在哪个方向滚动到该元素id设置
:唯一值切不能为数字开头(后续需该值赋给scroll-into-view
)
JS
js
// 定义数据
const category = reactive({
idx: 0,
coffeeList: [],
categoryMenuIntoView: 'category-menu-0',
coffeeIntoView: 'category-coffee-0'
})
/**
* 点击切换左侧menu
*/
const switchCategoryMenu = (item, index) => {
if (category.idx == index) return console.log('点击即为当前选中分类,无需切换逻辑')
category.idx = index
category.categoryMenuIntoView = `category-menu-${index}`
category.coffeeIntoView = `category-coffee-${index}`
}
/**
* onLoad之后执行,预先计算出右侧锚点卡片的范围
*/
const getDistanceToTop = () => {
distanceList.value = []; // 清空旧的距离列表
const selectorQuery = uni.createSelectorQuery();
selectorQuery.selectAll('.coffee-box').boundingClientRect(rects => {
console.log('rects.map(rect => rect.top)', rects.map(rect => rect.top))
distanceList.value = rects.map(rect => rect.top); // 直接映射为 `top` 值
}).exec();
}
/**
* 节流监听右侧区域滚动,联动左侧menu锚点定位
* 根据滚动出的距离,属于getDistanceToTop对应的哪一个范围,动态修改左侧scroll-into-view的值即可
*/
const coffeeScroll = throttle((event) => {
let scrollTop = event.detail.scrollTop;
}, 200); // 节流时间 300ms
如此即可实现锚点定位功能。(滚动监听功能后续可能会更新)