Uniapp实现锚点跳转和滚动监听(不用scroll-view)微信小程序版

在这里插入图片描述
点击上面的商品,评价,详情可以滚动到相应的地方,当从上往下滑动的时候,滑到某个地方相应的tab就会被选中

我之前的博客写过一个用scroll-view实现这个功能的demo,这篇就不用scroll-view实现。(有兴趣的可以去看看哦,第3篇)

先说这一块,锚点跳转

在这里插入图片描述

<view class="navs-nav" :class="{ navactivetext: index == num }" :style=" 'height:' + tophight.height + 'px;' + 'line-height:' + tophight.height + 'px;' "
@click="navbtn(index)">{
   
   {item.name}}</view>

说明一下:style是我把小程序默认的导航栏去掉了,返回获取了那3个点和圆环到顶部的距离

navactivetext这个就是动态绑定的css,这没啥好说的

再来说点击事件

首先点击商品这个tab,我们肯定是让它直接返回顶部的,所以需要做一个判断


   navbtn(index) {
			this.num = index
			 if (index === 0) {
				 this.backTop()
			} else {
				const data = {
					isScroll:false,
					index:index
				}
				//调用父组件的事件
				this.$parent.fatherMethod(data)
			}
},
// 回到顶部
		backTop() {
				wx.pageScrollTo({
					scrollTop: 0,
				    duration:300
			})
	}

因为我们这个是一个子组件,需要调用父组件的事件,因为是自己的练习项目,所以用了$parent,实际开发最好不要这样用哈

然后到父组件啦

	fatherMethod(data) {
		this.isScroll = data.isScroll
		let hei = this.tophight.top + this.tophight.height
		let clsdata = data.index === 1 ? '.evaluate' : '.product'
		const query = this.createSelectorQuery();
		query.select(clsdata).boundingClientRect()
		query.selectViewport().scrollOffset();
		query.exec((res) => {
				if (res[0] && res[1]) {
					uni.pageScrollTo({
						scrollTop: res[0].top + res[1].scrollTop - hei,
						duration: 300
					})
					setTimeout(()=>{
						this.isScroll = true
					},1000)
				}
			})
		}

1.this.isScroll = data.isScroll 这个是为了不和onPageScroll产生冲突,我一时没想到啥解决的办法,如果你们有好的方法记得@我一下哈,多谢

2.这个hei也是因为我把小程序默认的导航栏去掉了,所以才要减去,你们可以根据实际情况来计算

3…evaluate就是我们的评价组件,给它绑定了一个class,同理.product也是我们的详情组件

剩下的就没啥说的了呀

然后再说我们的滚动监听,滑动一定位置,我们的tab加上class

在父组件中

首先利用computed计算出,评价和详情距离顶部的距离

Distance(){
	this.$nextTick(()=>{
		let hei = this.tophight.top + this.tophight.height
		const query = this.createSelectorQuery();
		query.select('.evaluate').boundingClientRect()
		query.selectViewport().scrollOffset();
		query.exec((res) => {
			  this.evaluateDistance =  res[0].top  - hei
		})
		query.select('.product').boundingClientRect()
		query.selectViewport().scrollOffset();
		query.exec((res) => {
		this.productDistance =  res[1].scrollHeight
		
		})
	})

},

然后利用onPageScroll

 onPageScroll(e) {
		let scrollTop = e.scrollTop
		let that = this
		if(that.isScroll === true){
		function scrollCurrentIndex(param){
			let distance = [that.productDistance,that.evaluateDistance-20,0]
			let currentIndex = [2,1,0]
			 for (let i = 0; i < distance.length; i++) {
			        if (param >= distance[i]) {
			            return currentIndex[i];
			        };
			    };
			 return currentIndex[currentIndex.length - 1];
		}
		const level = scrollCurrentIndex(scrollTop)
		this.currentIndex = level
		}

}

再说一下下,由于是自己练习的项目,距离啥的并不是特别的准备,大家可以自己进行判断哈,这段就是判断距离最顶部的距离在哪个区间,就赋值给currentIndex,最通俗的方法就是这样写

if(scrollTop<=Number(this.evaluateDistance-20)){
				currentIndex = 0
		}else if(Number(this.evaluateDistance-20)<=scrollTop && scrollTop<=Number(this.productDistance)){
				currentIndex = 1
		}else{
				currentIndex = 2
		}
			this.currentIndex = currentIndex
		} 

我只是不想用这么多if,else…

然后就通过props把currentIndex传到子组件了

回到子组件

用props接收之后

watch:{
		currentIndex(newval){
			this.num = newval
		}
},

这样就ok啦

不过有一个问题,就是我上面说的那个用isScroll进行判断,避免锚点跳转的时候被onPageScroll所干扰,我这样做虽然可以实现,但是总感觉哪个地方不好,有小伙伴有更好的方法记得@我一下哈,谢谢啦

github上有详细的教程

github项目地址:https://github.com/lsh555/TmUniapp

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_45389051/article/details/111215009