1. html
<div class="contarner">
<div class="nav">
<a class="navItem active" href="javascript:void(0)">item1</a>
<a class="navItem" href="javascript:void(0)">item2</a>
<a class="navItem" href="javascript:void(0)">item3</a>
<a class="navItem" href="javascript:void(0)">item4</a>
</div>
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
</div>
2. less
*{
margin: 0;
padding: 0;
}
a{
text-decoration: none;
}
body,html{
overflow: height;
}
.contarner{
.item{
height: 100vh;
background: pink;
color:red;
font-size: 25px;
}
.nav{
background: #fff;
position: sticky;
top:0;
display: flex;
justify-content:space-between ;
padding:15px;
}
.nav .navItem{
color:#000;
}
.nav>.active{
color:pink;
}
}
3. js
// 导航
let nav = document.querySelector('.nav');
// 导航选项
let navItem = [...document.getElementsByClassName('navItem')];
// 内容区
let item = document.querySelectorAll('.item');
// 屏幕高度的一半
let cw = document.documentElement.clientHeight / 2;
// 导航栏的高度
let navHeight = nav.offsetHeight;
// 遍历导航绑定事件
navItem.forEach((val,index)=>{
val.onclick = function(e){
// 清除样式
navRemoveClass();
// 追加样式
navAddClass(index);
//获取当前索引
moveTO(index);
}
});
// 滑动屏幕到指定位置
function moveTO(index){
//该元素到顶部的距离
let top = item[index].offsetTop;
window.scrollTo({
top:top-navHeight,
behavior:'smooth'
});
}
//导航指定索引添加样式
function navAddClass(index){
navItem[index].classList.add('active');
}
// 删除指定索引的class
function navRemoveClass(){
document.querySelector('.nav>.active').classList.remove('active');
}
// 监听滚动事件
window.addEventListener('scroll',function(){
newdebounce();
});
//防抖函数(返回一个函数)
function debounce(func,timer){
let timeout;
return function(){
clearTimeout(timeout);
// 参数
let args = arguments;
timeout = setTimeout(function(){
func.apply(null, args)
},timer)
}
}
// 滚动条滚动处理
let newdebounce = debounce(function(a,b,c,d){
let bodyScrollTop = document.documentElement.scrollTop + cw;
for(let key in item){
if(item[key].offsetTop <= bodyScrollTop){
// 删除class
navRemoveClass();
// 添加class
navAddClass(key);
}
}
},10);