-
横向滚动时,外部容器tab_scroll_box设置高度和强制不换行white-space: nowrap;,内部子元素tab_item设置display: inline-block;。
-
锚点定位 外部容器设置属性scroll-with-animation :scroll-into-view="'tab' + curIndex",内部子元素设置属性id,:id="'tab' + curIndex"。
-
无论横向还是竖向滚动,都需要给scroll-view容器一个高度。
-
竖向滚动展示列表数据时,使用@scrolltolower事件触底添加数据。
-
在滚动 scroll-view 时会阻止页面回弹,因此无法触发 onPullDownRefresh。
-
使用scroll-view时,小程序页面点击顶部状态栏无法实现回到页面顶部。
-
不可以同时设置scroll-into-view和scroll-top(scroll-left)属性,scroll-into-view 的优先级高于 scroll-top(scroll-left)。
-
当scroll-view是别的元素控制滑动而自身不可以滚动时,可以在自身scroll-view里包一层元素,添加catchtouchmove="false"禁止自身手动滑动。
7示例:当页面竖向滚动超过一定距离时,显示tab列表可选择,实现(1)点击tab页面自动滑动到相关内容(2)页面滑动时tab自动选中。
.tab_scroll{
background: #fff;
height: 62rpx;
white-space: nowrap;
.tab_item{
font-size: 32rpx;
line-height: 60rpx;
border-radius: 100rpx;
display: inline-block;
text-align: center;
color: #666666;
padding: 0 24rpx;
&.active {
color: #ED6539;
}
}
.active {
color: #333;
}
}
.tab_scroll_fixed{
position: fixed;
width: 100%;
top: 0;
left: 0;
z-index: 11;
}
<scroll-view scroll-x v-if="showTab" class="tab_scroll tab_scroll_fixed" id="tabs" scroll-with-animation :scroll-into-view="'tab' + curIndex" :style="{'display': showTab ? 'block': 'none'}">
<view v-for="(item, index) in tabList" :key="index" :id="'tab' + index" :class="['tab_item', {'active': curIndex == index}]" @click="changeTab(item,index)">
{{item.label}}
</view>
</scroll-view>
onPageScroll (event) {
if (this.isTabChange) {
return
}
const { scrollTop } = event
const skewY = uni.upx2px(388) // 388为顶部轮播图片高度,因为是uni-app使用rpx,需要换算为px单位
if (scrollTop >= skewY) { // 当图片滚动出页面范围时显示tab
this.showTab = true
this.$nextTick(() => {
const length = this.distanceArr.length
const index = this.distanceArr.findIndex(el => el - uni.upx2px(62) - scrollTop > 0)
// 当index == -1 的时候,实际当前滚动的距离超出了最大值,也就是在最后一个tab显示的内容
// 当index > 0 的时候,说明能在当前的scrollTop值找到,即index的前一位
this.curIndex = index > 0 ? index - 1 : length - 1
})
} else {
this.showTab = false
}
}
// 获取所有元素在当前页面所处的位置信息
getDistanceArr () {
this.tabList.map(el => {
uni.createSelectorQuery().select(el.key).boundingClientRect(data => {
// 获取当前ID距离顶部的top值
this.distanceArr.push(data.top)
}).exec()
})
},
changeTab (item, index) {
this.isTabChange = true
// this.$nextTick 保证当前isTabChange 为true后执行代码
// 避免在istabChange变为true的时候,执行代码,监听事件还是会继续执行重新计算currenTab值
this.$nextTick(() => {
this.curIndex = index
console.log(item.key, typeof item.key)
uni.createSelectorQuery().select(item.key).boundingClientRect(data => {
uni.createSelectorQuery().select('.device_detail').boundingClientRect(res => {
const scrollTop = data.top - res.top // 获取差值
const skewY = uni.upx2px(62) // 偏移
// 页面开始进行滚动到目标位置
uni.pageScrollTo({
scrollTop: scrollTop > 0 ? scrollTop - skewY : scrollTop + skewY,
duration: 300,
complete: () => {
const timer = setTimeout(() => {
this.isTabChange = false // 关闭
clearTimeout(timer)
}, 500) // 解决ios和安卓、鸿蒙系统兼容性问题
}
})
}).exec()
}).exec()
})
}