场景:假设一个页面分为四个板块,每个板块为一个组件,顶部是四个tab按钮,点击哪个按钮页面就自动定位到对应的版块,且按钮要高亮,若用户自己滑动页面,滑动到哪个板块区域,对应的tab按钮也要高亮
<template>
<scroll-view
@scroll="scroll"
@scrolltolower="onreachBottom"
scroll-y
style="width: 100%; height: 100%; overflow: hidden auto"
id="scroll-view-id"
>
<view class="module-tabs">
<view
class="tabs-button"
:class="{ active: menuIndex == item.hook }"
v-for="(item, index) in tabsList"
:key="index"
@click="hookTo(item.hook)"
>
{{ item.name }}
</view>
</view>
<view class="">
<view>
<news
ref="news"
:id="`${platClass}-news`"
:platform="platform"
></news>
</view>
<view>
<using-manaual
ref="usingManaual"
:id="`${platClass}-manaual`"
:platform="platform"
></using-manaual>
</view>
<view>
<learn-zone
ref="learnZone"
:id="`${platClass}-learn`"
:platform="platform"
></learn-zone>
</view>
<view>
<video-learning
ref="videoLearning"
:id="`${platClass}-video`"
:platform="platform"
></video-learning>
</view>
<view style="height: 1px"></view>
</view>
</scroll-view>
</template>
<script>
import news from "../components/news.vue";
import usingManaual from "../components/usingManaual.vue";
import learnZone from "../components/learnZone.vue";
import videoLearning from "../components/videoLearning.vue";
export default {
components: {
news,
usingManaual,
learnZone,
videoLearning,
},
props: {
platform: {
type: String,
default: () => {
return "";
},
},
platClass: {
type: String,
default: () => {
return "";
},
},
tabsList: {
type: Array,
default: () => {
return [];
},
},
current: {
type: Number,
default: () => {
return 0;
},
},
},
data() {
return {
scrollAy: 0,
scrollBy: 0,
scrollCy: 0,
scrollDy: 0,
scrollAx: 0,
scrollBx: 0,
scrollCx: 0,
scrollDx: 0,
menuIndex: "",
viewHight: "",
scrollFlag: false,
scrollView: "",
bottomFlag: false,
};
},
mounted() {
this.menuIndex = `${this.platClass}-news`;
},
methods: {
onreachBottom(e) {
let vm = this;
console.log("222222222", e);
vm.bottomFlag = true;
console.log("-------vm.bottomFlag-222222-----", vm.bottomFlag);
},
getScrollHeight() {
let vm = this;
//getBoundingClientRect().y在这里不适用,固先注销掉
// vm.scrollAy = document
// .querySelector(`#${vm.platClass}-news`)
// .getBoundingClientRect().y;
// vm.scrollBy = document
// .querySelector(`#${vm.platClass}-manaual`)
// .getBoundingClientRect().y;
// vm.scrollCy = document
// .querySelector(`#${vm.platClass}-learn`)
// .getBoundingClientRect().y;
// vm.scrollDy = document
// .querySelector(`#${vm.platClass}-video`)
// .getBoundingClientRect().y;
vm.scrollAx = document
.querySelector(`#${vm.platClass}-news`)
.getBoundingClientRect().x;
vm.scrollBx = document
.querySelector(`#${vm.platClass}-manaual`)
.getBoundingClientRect().x;
vm.scrollCx = document
.querySelector(`#${vm.platClass}-learn`)
.getBoundingClientRect().x;
vm.scrollDx = document
.querySelector(`#${vm.platClass}-video`)
.getBoundingClientRect().x;
},
hookTo(name) {
let vm = this;
let hook = `#${name}`;
let hookEl = document.querySelector(hook);
//获取各个组件的最顶层父组件,只有最顶层父组件才是实现可滚动的元素
let scrollEl = hookEl.parentNode.parentNode.parentNode.parentNode;
let scrollAy = document.querySelector(
`#${vm.platClass}-news`
).offsetHeight;
let scrollBy = document.querySelector(
`#${vm.platClass}-manaual`
).offsetHeight;
let scrollCy = document.querySelector(
`#${vm.platClass}-learn`
).offsetHeight;
let scrollDy = document.querySelector(
`#${vm.platClass}-video`
).offsetHeight;
let clientHeight =
document.querySelector("#scroll-view-id").offsetHeight;
//由于scrollIntoView方法定位的位置精确度不高,固弃用该方法
// hookEl.scrollIntoView();
//采用scrollTo配合设置的锚点来自动滚动到指定区域
switch (name) {
case `${this.platClass}-news`:
scrollEl.scrollTo(vm.scrollAx, 0);
vm.menuIndex = `${this.platClass}-news`;
break;
case `${this.platClass}-manaual`:
scrollEl.scrollTo(vm.scrollBx, scrollAy * 0.8 + 16);
console.log("-------scrollAy + 16", scrollAy);
vm.menuIndex = `${this.platClass}-manaual`;
vm.scrollAy = scrollAy;
break;
case `${this.platClass}-learn`:
scrollEl.scrollTo(vm.scrollCx, scrollAy + scrollBy + 32);
vm.menuIndex = `${this.platClass}-learn`;
break;
case `${this.platClass}-video`:
scrollEl.scrollTo(
vm.scrollDx,
scrollAy + scrollBy + scrollCy + 48
);
vm.menuIndex = `${this.platClass}-video`;
break;
default:
break;
}
},
//scroll-view的滚动事件
scroll(e) {
let vm = this;
console.log("-----------eeeeeeee", e.detail.scrollTop);
//获取滚动长度
let scrollTop = e.detail.scrollTop;
//获取各个组件的高度
let scrollAy = document.querySelector(
`#${vm.platClass}-news`
).offsetHeight;
let scrollBy = document.querySelector(
`#${vm.platClass}-manaual`
).offsetHeight;
let scrollCy = document.querySelector(
`#${vm.platClass}-learn`
).offsetHeight;
let scrollDy = document.querySelector(
`#${vm.platClass}-video`
).offsetHeight;
console.log(
"------scroll-view的滚动事件-222222222222---------",
scrollAy,
scrollBy,
scrollCy,
scrollDy
);
if (scrollTop < scrollAy / 2) {
this.menuIndex = `${this.platClass}-news`;
}
if (scrollTop > scrollAy * 0.8) {
this.menuIndex = `${this.platClass}-manaual`;
}
if (scrollTop > scrollAy * 0.8 + scrollBy / 2) {
this.menuIndex = `${this.platClass}-learn`;
}
if (scrollTop > scrollAy + scrollBy + scrollCy / 4) {
this.menuIndex = `${this.platClass}-video`;
}
},
},
};
</script>
<style scoped lang="less">
.module-tabs {
display: flex;
padding: 8rpx 24rpx 30rpx;
background: #fff;
position: fixed;
z-index: 99;
top: 0;
width: 100%;
.tabs-button {
width: 160rpx;
height: 68rpx;
background: #f3f4f7;
border-radius: 8rpx;
font-size: 28rpx;
text-align: center;
line-height: 68rpx;
margin-right: 20rpx;
}
.tabs-button.active {
border: 1px solid #0a63f1;
color: #0a63f1;
}
}
</style>