注:mescroll中监听滚动事件必须要在upOption中配置onScroll:true
在页面中
<mescroll-uni :down="downOption" @down="downCallback" :up="upOption" @up="upCallback" @init="mescrollInit" top="280"@scroll="rightScroll">
<view>
<view class="class-item" :id="'item' + index1" v-for="(item1, index1) in list" :key="index1">
<view>{{item1.day}}</view>
<view v-for="(item, index) in item1.list" :key="index">
<view class="flex-row justify-center align-center margin-top-20 padding-bottom-20" :class="index + 1 != list.length ? 'xian' : ''">
<view class="flex-column list-center margin-left-40 margin-top-10">
<view class="title-view">
<text>{{item.title}}</text>
</view>
<view class="flex-row margin-top-10">
<view class="row-gray text-sm">{{item.data}}</view>
<view class="row-gray text-sm"> {{item.data1}}</view>
</view>
</view>
</view>
</view>
</view>
</view>
</mescroll-uni>
在页面加载完成之后
onReady() {
this.getMenuItemTop()
},
在methods中
async change(index) {
if (this.arr.length == 0) {
await this.getMenuItemTop();
}
if (index == this.current) return;
this.mescroll.scrollTo(this.oldScrollTop)
this.$nextTick(function() {
this.mescroll.scrollTo(this.arr[index])
this.current = index;
this.dateMonth = index + 1;
})
// this.getDataList(this.mescroll)
},
// 获取右边菜单每个item到顶部的距离
getMenuItemTop() {
new Promise(resolve => {
let selectorQuery = uni.createSelectorQuery();
selectorQuery.selectAll('.class-item').boundingClientRect((rects) => {
// 如果节点尚未生成,rects值为[](因为用selectAll,所以返回的是数组),循环调用执行
if (!rects.length) {
setTimeout(() => {
this.getMenuItemTop();
}, 10);
return;
}
rects.forEach((rect) => {
// 这里减去rects[0].top,是因为第一项顶部可能不是贴到导航栏(比如有个搜索框的情况)
this.arr.push(rect.top - rects[0].top);
resolve();
})
}).exec()
})
},
// 获取一个目标元素的高度
getElRect(elClass, dataVal) {
new Promise((resolve, reject) => {
const query = uni.createSelectorQuery().in(this);
query.select('.' + elClass).fields({
size: true
}, res => {
// 如果节点尚未生成,res值为null,循环调用执行
if (!res) {
setTimeout(() => {
this.getElRect(elClass);
}, 10);
return;
}
this[dataVal] = res.height;
resolve();
}).exec();
})
},
//监听mescroll的滚动
async rightScroll(e) {
this.oldScrollTop = e.scrollTop;
if (this.arr.length == 0) {
await this.getMenuItemTop();
}
if (this.timer) return;
if (!this.menuHeight) {
await this.getElRect('menu-scroll-view', 'menuHeight');
}
setTimeout(() => { // 节流
this.timer = null;
// scrollHeight为右边菜单垂直中点位置
let scrollHeight = e.scrollTop + this.menuHeight / 2;
for (let i = 0; i < this.arr.length; i++) {
let height1 = this.arr[i];
let height2 = this.arr[i + 1];
// 如果不存在height2,意味着数据循环已经到了最后一个,设置左边菜单为最后一项即可
if (!height2 || scrollHeight >= height1 && scrollHeight < height2) {
this.current = i;
return;
}
}
}, 10)
},
参考uview代码实现https://www.uviewui.com/