uniapp 小程序 锚点滚动菜单

曹え 5811 发布于:2023-05-25 05:02:02

导航tab

<u-sticky>
			<view class="m-info2">
				<u-tabs :current="currentTab" :list="list1" :scrollable="false" :activeStyle="{color: '#26a734'}" :inactiveStyle="{color: '#7c878e'}" lineColor="#26a734"  @change="change"></u-tabs>
			</view>
		</u-sticky>


锚点内容

<view class="box" id="q1"></view>
<view class="box" id="q2"></view>
<view class="box" id="q3"></view>
<view class="box" id="q4"></view>


js


onLoad 里面,或者接口加载完成后,执行下面的的方法,用于获得每个锚点的位置

this.getDistanceArr()


data

showTabs: false,
isTabChange: false,
currentTab:0,
distanceArr: [],
list1:[
{name:'简介',id:'#q1'},
{name:'详情',id:'#q2'},
{name:'合作洽谈',id:'#q3'},
{name:'推荐',id:'#q4'}
],


methods: 里面

clickItem(item) {
							console.log(item)
						    this.isTabChange = true
						    const _this = this
						    // this.$nextTick 保证当前isTabChange 为true后执行代码
						    // 避免在istabChange变为true的时候,执行代码,监听事件还是会继续执行重新计算currenTab值
						    this.$nextTick(() => {
						        _this.currentTab = item.index
						        uni.createSelectorQuery().select(item.id).boundingClientRect(data => {
						            uni.createSelectorQuery().select('.page').boundingClientRect(res => {
						                const scrollTop = data.top - res.top // 获取差值
						                const skewY = 50 // 偏移
						                // 页面开始进行滚动到目标位置
						                uni.pageScrollTo({
						                    // scrollTop的计算需要注意,在往上或者是往下拉的时候 需要加减 吸顶的高度
						                    scrollTop: scrollTop > 0 ? scrollTop - skewY :  scrollTop + skewY,
						                    duration: 300,
						                    complete: function () {
						                        const timer = setTimeout(() => {
						                            _this.isTabChange = false // 关闭
						                            clearTimeout(timer)
						                        }, 500)
						                        // 真机在测试<500ms的时候,ios无问题,但是安卓和鸿蒙都会在变为false的时候,
						                        //再次触发onPageScroll事件,避免兼容性问题,将值改为500ms,
						                        //解决ios和安卓、鸿蒙系统兼容性问题
						                    }
						                });
						            }).exec()
						        }).exec()
						    })
						},
						 // 获取所有元素在当前页面所处的位置信息
						    getDistanceArr () {
						        const _this = this
						        _this.list1.map(el => {
						            uni.createSelectorQuery().select(el.id).boundingClientRect(data => {
						                // 获取当前ID距离顶部的top值
						                _this.distanceArr.push(data.top)
						            }).exec()
						        })
								console.log(_this.distanceArr)
						    }


下面的 和 onLoad 同级

onPageScroll(event) { //根据距离顶部距离是否显示回到顶部按钮
		    if (event.scrollTop > 10) { //当距离大于10时显示回到顶部按钮
		        this.flag = true
		    } else {
		        this.flag = false
		    }
			
				const _this = this
			    if (this.isTabChange) {
			            return
			    }
			    const { scrollTop } = event;
			    // 偏移量,由于吸顶的tab、头部的显示信息也有高度,素以做了偏移量
			    const skewY = 55 
			    if (scrollTop >= skewY) {
			        // 在未显示tab并且 currentTab <= 0时,防止uview ui抖动bug,设置默认复位值
			        if (!this.showTabs && this.currentTab <= 0) { 
			                this.currentTab = 0
			        }
			        this.showTabs = true
			        this.$nextTick(() => {
			            const length = this.distanceArr.length
			            const index = this.distanceArr.findIndex(el => el - skewY - scrollTop > 0)
			            // 当index  == -1 的时候,实际当前滚动的距离超出了最大值,也就是在最后一个tab显示的内容
			            // 当index > 0 的时候,说明能在当前的scrollTop值找到,即index的前一位
			            this.currentTab = index > 0 ? index - 1 : length - 1
			        })
			    } else {
			        this.showTabs = false
			    }
		},


觉得有用请点个赞吧!
0 178