uniapp基于mescroll实现滑动和点击联动效果

注: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/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值