组件传入一个原生DOM的数组
<template>
<div class="tab_content">
<transition name="fade">
<div ref="maxSidebar" class="tab-box">
<template v-for="(item, index) in silderDomList">
<p
:class="{ tabAtive: currentIndex === index }"
:key="index"
@click="changeScroll(index)"
>
<span v-html="item.txt"></span>
<i class="line" :key="index + 6"></i>
</p>
</template>
</div>
</transition>
</div>
</template>
<script>
export default {
props: {
// 文本内容
silderDomList: {
type: Array,
default: () => []
}
},
data () {
return {
// 当前导航
currentIndex: 0,
canScroll: true
}
},
methods: {
// 返回顶部
backTop () {
if (!this.canScroll) return
let top = document.documentElement.scrollTop || document.body.scrollTop
// 实现滚动效果
const timeTop = setInterval(() => {
document.body.scrollTop = document.documentElement.scrollTop = top -= 50
if (top <= 0) {
clearInterval(timeTop)
this.canScroll = true
}
}, 8)
},
changeScroll (idx) {
if (!this.canScroll) return
// 点击判断当前距离顶部的距离,
let distance = this.silderDomList[idx].dom.getBoundingClientRect().top
if (distance === 60 || distance === -60) return
// 获取现在滚动距离
let top = document.documentElement.scrollTop || document.body.scrollTop
// true上边移动+,false下移-
let direction = true
if (distance >= 0) {
direction = true
// if(distance==0) return
} else {
direction = false
// distance -= 60
idx != 0 ? (distance -= 60) : (distance -= 120)
}
// 记录已滚动距离
let long = 0
// 定时器滚动距离
const timeTop = setInterval(() => {
// 移动指定距离 true上边移动+,false下移-
let speed = 50
// 上滑
if (direction) {
// 如果当前已经到页面底部,那么直接return
if (this.isBottom()) {
clearInterval(timeTop)
return
}
// 记录下每次位移的距离
long += 50
if (long > distance) {
speed = distance % speed
}
document.body.scrollTop = document.documentElement.scrollTop = top += speed
if (long >= distance) {
clearInterval(timeTop)
// 如果当前高亮的不是选中的,那么再次递归调用自身,需要等网络请求全都结束了再判断重新滚动
this.$nextTick(() => {
if (this.currentIndex != idx) {
return this.changeScroll(idx)
}
this.canScroll = true
})
}
} else {
// 如果已经在页面顶部,那么直接return
if (this.isTop()) {
clearInterval(timeTop)
return
}
// 下滑,回到顶部类似
long -= 50
if (long < distance) {
speed = distance % speed
}
document.body.scrollTop = document.documentElement.scrollTop = top -= speed
if (long <= distance) {
clearInterval(timeTop)
this.canScroll = true
}
}
}, 8)
},
// 改变当前高亮的=
changeActive () {
// 滚动的时候判断当前的DOMS数组里面的定位,距离顶部的
// 因为顶部工具栏距离60
let index = 0
// 下滚找最后一个,上滚找第一个
this.silderDomList.forEach((item, idx) => {
// console.log(item);
// console.log(item.dom.getBoundingClientRect())
item.dom.getBoundingClientRect().top <= 60 && (index = idx)
})
// 如果到底部,那么默认就是最后一个
if (this.isBottom()) {
index = this.silderDomList.length - 1
}
// console.log(11111,this.isBottom());
this.currentIndex = index
},
// 是否到底部的方法
isBottom () {
// 文档实际高度减去页面可视高度就是滚动条高度
const scrollTop =
document.documentElement.scrollTop || document.body.scrollTop || 0
const scollHeight =
Math.max(
document.body.scrollHeight,
document.documentElement.scrollHeight
) - this.getClientHeight()
// 到底部
// console.log(scollHeight,scrollTop);
return scollHeight <= scrollTop
},
// 是否到顶部的方法
isTop () {
// 文档实际高度减去页面可视高度就是滚动条高度
const scrollTop =
document.documentElement.scrollTop || document.body.scrollTop || 0
// console.log(scollHeight,scrollTop);
return scrollTop <= 0
},
//获取当前可视范围的高度
getClientHeight () {
let clientHeight = 0
if (document.body.clientHeight && document.documentElement.clientHeight) {
clientHeight = Math.min(
document.body.clientHeight,
document.documentElement.clientHeight
)
} else {
clientHeight = Math.max(
document.body.clientHeight,
document.documentElement.clientHeight
)
}
return clientHeight
}
},
mounted () {
window.addEventListener('scroll', this.changeActive)
},
destroyed () {
window.removeEventListener('scroll', this.changeActive)
}
}
</script>
<style lang="scss" scoped>
.tab_content {
position: sticky;
top: 0;
z-index: 99999;
width: 100%;
height: 50px;
background: linear-gradient(0deg, #ffffff, #ffffff),
linear-gradient(180deg, #d9edff 0%, #ffffff 100%);
box-shadow: 0px 1px 12px rgba(102, 157, 208, 0.1);
}
.tab-box {
margin: 0 auto;
// width: 1200px;
// padding: 0 405px;
height: 100%;
min-width: 1072px;
display: flex;
align-items: center;
justify-content: center;
.tabAtive {
color: #2998ff;
border-bottom: 3px solid #2998ff;
}
p {
float: left;
position: relative;
font-family: 'PingFang SC';
font-style: normal;
font-weight: 500;
font-size: 14px;
line-height: 47px;
color: rgba(55, 56, 73, 0.45);
margin: 0 60px;
cursor: pointer;
border-bottom: 3px solid transparent;
}
}
</style>