1、我们先写好我们的html结构,一个nav导航栏
<div class="product_nav">
<div class="product_nav_box1 scollNavItem" :class="{ 'product_nav_box_active' is_Active === 1 }"
@click="skipTo('.product_cont2', 1)">个性化定制</div>
<div class="product_nav_box2 scollNavItem" :class="{ 'product_nav_box_active': is_Active === 2 }"
@click="skipTo('.product_cont3', 2)">数据运营</div>
<div class="product_nav_box3 scollNavItem" :class="{ 'product_nav_box_active': is_Active === 3 }"
@click="skipTo('.product_cont4', 3)">学员订单管理</div>
<div class="product_nav_box4 scollNavItem" :class="{ 'product_nav_box_active': is_Active === 4 }"
@click="skipTo('.product_cont5', 4)">退款明细</div>
<div class="product_nav_box5 scollNavItem" :class="{ 'product_nav_box_active': is_Active === 5 }"
@click="skipTo('.product_cont6', 5)">分校区管理</div>
</div>
2、设置我们的样式
.product_nav {
display: flex;
width: 80%;
height: 6.25rem;
position: absolute;
left: 10%;
top: 26.875rem;
background-color: #fff;
border-radius: 1.6875rem 1.6875rem 1.6875rem 1.6875rem;
overflow: hidden;
box-shadow: 0.4375rem 0.4375rem 0.75rem rgba(0, 0, 0, 0.4),
-0.4375rem -0.4375rem 0.75rem rgba(255, 255, 255, 0.9);
.product_nav_box1,
.product_nav_box2,
.product_nav_box3,
.product_nav_box4,
.product_nav_box5 {
cursor: pointer;
text-align: center;
line-height: 6.25rem;
width: calc(100% / 7);
height: 100%;
font-size: 24px;
color: #333;
font-weight: 400;
}
.product_nav_box4 {
border-radius: 0 1.6875rem 1.6875rem 0;
}
.product_nav_box5 {
border-radius: 1.6875rem 0 0 1.6875rem;
}
.product_nav_box_active {
background: linear-gradient(270deg, #2A8DFC 0%, rgba(35,127,251,0.59) 74%, #B5CEFF 100%);
color: #fff;
}
}
.is_noShow {
opacity: 0;
transition: all .8s;
}
.is_Show {
opacity: 1;
transition: all .8s;
}
.is_fixed {
text-align: center;
position: fixed;
top: 5.375rem;
left: 10%;
z-index: 98;
width: 80%;
height: 100px;
border-radius: 1.6875rem 1.6875rem 1.6875rem 1.6875rem;
background-color: #fff;
.scollNavItem {
line-height: 100px;
}
}
3、 设置锚点和nav
mounted () {
//监听滚动
window.addEventListener('scroll', this.fiexdNav)
},
data () {
return {
isFixed: false,
scrollTop: 430, //距离顶部的距离
offsetTop: 0
}
},
// 固定nav,页面滑动,锚点选中
fiexdNav () {
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop
// console.log(scrollTop)
const nav = document.querySelector('.product_nav')
if (scrollTop > this.scrollTop) {
nav.classList.add('is_fixed')
}
if(scrollTop >= 6609) {
nav.classList.add('is_noShow')
}else if(scrollTop <= 6609) {
nav.classList.remove('is_noShow')
}
if(scrollTop < this.scrollTop){
nav.classList.remove('is_fixed')
}
// 获取所有锚点元素
const contents = document.querySelectorAll('.scollItem')
// 锚点收集
const contentsOffsetTop = []
contents.forEach(item => {
contentsOffsetTop.push(item.offsetTop)
})
const pageHeight = window.innerHeight
// 获取nav的子元素
const navChildren = document.querySelectorAll('.scollNavItem')
for (let i = 0; i < contentsOffsetTop.length; i++) {
if (i === 0) {
navChildren[0].classList.add('product_nav_box_active')
} else if (scrollTop > contentsOffsetTop[i - 1] + pageHeight / 3) {
for (let j = 0; j < contentsOffsetTop.length; j++) {
// 排他
navChildren[j].classList.remove('product_nav_box_active')
navChildren[i].classList.add('product_nav_box_active')
}
} else {
navChildren[i].classList.remove('product_nav_box_active')
}
}
},
// 点击nav选中锚点元素
skipTo (selector, active) {
// ** 这里是为了调整页面的布局,当选中第一个items的时候,nav并没有贴在页面的最顶端
// ** navHeight + 86 所以在这里多减去一个nav的高度。
if (active == 6) {
this.listBoxState = true
const navHeight = document.querySelector('.product_nav').offsetHeight
const target = document.querySelector(selector)
target.scrollIntoView({ behavior: 'smooth' })
window.scrollTo({top:target.offsetTop - navHeight + 86,behavior:'smooth'})
}else {
const navHeight = document.querySelector('.product_nav').offsetHeight
const target = document.querySelector(selector)
target.scrollIntoView({ behavior: 'smooth' })
// ** behavior:'' 是定义锚点滚动时候一个切换效果,
// ** 默认的是auto。直接切换
// ** smooth,平滑过渡
window.scrollTo({top:target.offsetTop - navHeight, behavior: 'smooth'})
}
},
},