最近在写一个项目,大概有两个需求
1、锚点在页面里平滑跳转,无网址后面的#什么的,地址栏里只会看到默认网址
2、锚点随着页面滚动定位,并高亮定位的锚点
我上网查了资料,都是用一些框架,组件来完成,我我始终认为,框架只是加速开发的工具,开发者仍需具备独立的技能,不能说脱离框架就无法开发,所以我这里采用了原生的实现方式,代码很简单,我这里直接上源代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
nav {
width: 100%;
height: 10vh;
position: fixed;
left: 0;
top: 0;
background-color: aliceblue;
display: flex;
align-items: center;
}
nav a {
text-decoration: none;
font-size: 25px;
margin-right: 20px;
padding: 0 20px;
line-height: 10vh;
color: black;
}
nav a:hover {
color: #F00;
text-decoration: underline;
}
nav a.active {
color: #00F; /* 选中的链接的颜色 */
font-weight: bold; /* 使活动链接更明显 */
text-decoration: underline;
}
.page {
text-align: center;
font-size: 50px;
}
#home {
background-color: #F1F4F1;
height: 100vh;
line-height: 100vh;
}
#about {
background-color: #CACCCA;
height: 90vh;
line-height: 90vh;
}
#contact {
background-color: #EFF2EF;
height: 90vh;
line-height: 90vh;
}
</style>
</head>
<body>
<nav>
<a href="#home" data-target="#home">首页</a>
<a href="#about" data-target="#about">关于我们</a>
<a href="#contact" data-target="#contact">联系我们</a>
</nav>
<main class="pages">
<div class="page" id="home">首页</div>
<div class="page" id="about">关于我们</div>
<div class="page" id="contact">联系我们</div>
</main>
<script>
//地址栏里只会看到默认网址
document.querySelectorAll('nav a').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault(); // 阻止默认行为
// 获取目标页面的 ID
let targetId = this.getAttribute('data-target');
let targetElement = document.querySelector(targetId);
// 平滑滚动到目标元素
targetElement.scrollIntoView({
behavior: 'smooth'
});
// 更新导航栏的 active 状态
document.querySelectorAll('nav a').forEach(link => {
link.classList.remove('active');
});
this.classList.add('active');
});
});
//锚点随着页面滚动定位,并高亮定位的锚点
const io = new IntersectionObserver((entries) => {
let entry = entries.reduce((a, b) => {
return a.intersectionRatio > b.intersectionRatio ? a : b;
});
let id = entry.target.getAttribute('id');
console.log(id);
// 取消上一次高亮元素
document.querySelectorAll('nav a').forEach(link => {
link.classList.remove('active');
});
document.querySelector(`nav a[href="#${id}"]`).classList.add('active');
}, {
root: null,
rootMargin: '0px',
threshold: 0.6
});
const pages = document.querySelectorAll('.page');
pages.forEach(page => {
io.observe(page);
});
</script>
</body>
</html>