通过点击左侧菜单选项卡,右侧内容区域滚动到对应的高度位置,同样,右侧内容区域滚动一定的距离后,左侧选项卡需要判断右侧内容是属于左侧哪个选项卡的内容。
1、左侧菜单点击事件的处理data选项数据为:
data() { return { cateList: [], //左侧分类列表 current: 0, //当前点击项 rectInfoList:[], tempCurrent:0, scrollTop:0,//左侧导航栏距离顶部的位置 } },
左侧菜单使用scroll-view渲染
<!-- 左侧菜单选项 --> <scroll-view :scroll-top="scrollTop" scroll-y="true" show-scrollbar="false"> <view> {{item.catename}} </view> </scroll-view>
通过动态类样式完成将current
值与index
索引绑定,以及通过menuTab
将index索引下标值作为参数传入。添加scroll-top
属性,每次切换菜单,都让滚动条与顶部保持一定的距离
2、右侧内容区域通过uni.createSelectorQuery()获取元素盒子的高度值 右侧内容区域
<!-- 右侧对应的商品展示 --> <view> <scroll-view :scroll-into-view="'cate'+tempCurrent" scroll-y="true" show-scrollbar="false" @scroll="getCurrentHeight"> <view> <view> --<text>{{item.catename}}</text>-- </view> <view> <image></image> <text>{{el.smalltitle}}</text> </view> </view> <view></view> </scroll-view> </view>
获取不同的id值的高度与H5类似,通过id选择器去获取元素的宽,高的详细信息,一开始top
为0,高度值赋给bottom
,然后下一次就变为上一个元素的bottom
值就是下一个元素的top
值,遍历完成后,把值整个存在一个数组中,作为对象数组进行存储。
// 获取与顶部之间的距离 getRectInfo() { var top = 0; var bottom = 0; var temp = 0; for (var i = 0; i < this.cateList.length; i++) { let view = uni.createSelectorQuery().in(this).select("#cate"+i); view.fields({ size: true, rect: true }, data => { top = temp; bottom = top + data.height; temp = bottom; this.rectInfoList[i] = { 'top':top, 'bottom':bottom } // console.log(top, bottom); }).exec(); } console.log(this.rectInfoList); },
3、右侧内容区滑动时判断对应的左侧索引下标值
当右侧滑动内容时,需要使用@scroll
事件绑定在scroll-view
上,然后e.detail.scrollTop
获取到的就是当前内容距离顶部之间的距离,通过拿到这个距离,再去与存储在数组中的每个模块的top
,bottom
值去匹配,如果currentHeight
(也就是当前的距离顶部的高度)满足其中的范围,那么就将对应的index
索引赋值到左侧菜单上去。
image.png
getCurrentHeight(e){ var currentHeight = e.detail.scrollTop; this.rectInfoList.forEach((item,index)=>{ if(currentHeight >= item.top && currentHeight <= item.bottom){ // 当前获取的盒子高度大于top小于bottom,判定将索引传至左侧菜单导航 this.current = index; this.scrollTop = index * uni.upx2px(100); } }) }
4、清空默认的滚动条
想要清空默认的滚动条,在scroll-view
中需要加入show-scrollbar="false"
以及在对应的style样式中去加入样式代码。
/deep/::-webkit-scrollbar { display: none; width: 0; height: 0; }
5、注意点
值得一提的是getRectInfo
函数需要在dom
树渲染完成后才可以进行调用,否则dom
树还未生成,获取到的信息是null
,因此,需要使用一个定时器去异步调用。并且该方法只能在mounted
生命周期中去使用。
mounted() { setTimeout(() => { this.getRectInfo(); }, 200) },