实现多粘性区块的锚点导航功能
实现多粘性区块的锚点导航功能
嘿,我懂你碰到的麻烦了!当所有section都设置成position: sticky; top: 0之后,它们其实都堆叠在视口顶部的同一位置,传统的锚点链接自然没法正常工作——毕竟浏览器找不到每个section对应的滚动偏移量嘛。不过用JavaScript完全能解决这个问题,我来帮你调整代码,让导航圆点既能随滚动高亮,点击也能精准跳转到对应区块。
首先先修正你HTML里的一个小错误:你的.scroll-control列表里多了一个多余的</a>标签,先把它删掉,不然会影响DOM结构。
接下来是完整的实现代码,我会把HTML、CSS和JavaScript整合到一起:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Sticky Sections with Dot Navigation</title> <style> body { margin: 0px; padding: 0px; scroll-behavior: smooth; /* 修正原语法错误:scroll: behavior smooth → scroll-behavior: smooth */ } section { position: sticky; width: 100%; height: 100vh; top: 0; display: inline-block; box-sizing: border-box; } .text { font-size: 40px; font-weight: 600; text-align: center; padding-top: 20vh; height: 100%; } .gray { background-color: #5c5d5f; } .red { background-color: #e31426; } .scroll-control { position: fixed; right: 70px; top: 40%; transform: translateY(-50%); /* 修正居中方向:原translateX改为Y轴居中 */ z-index: 700; list-style: none; /* 移除列表默认圆点 */ padding: 0; } .scroll-control a { text-decoration: none; /* 移除链接下划线 */ } .scroll-control a span { cursor: pointer; display: block; width: 12px; height: 12px; border-radius: 50%; margin: 30px 0; transition: all 0.3s ease; /* 添加过渡动画,让样式变化更丝滑 */ } .scroll-control a span:hover { opacity: 1; transform: scale(1.5); } .inactive { background-color: #000; opacity: 0.7; } .current { opacity: 1; background-color: #000; transform: scale(1.5); } </style> </head> <body> <ul class="scroll-control"> <li><a href="#1"><span class="one current"></span></a></li> <li><a href="#2"><span class="two inactive"></span></a></li> <li><a href="#3"><span class="three inactive"></span></a></li> <li><a href="#4"><span class="four inactive"></span></a></li> </ul> <section id="1" class="panel gray"> <div class="text">SECTION 1</div> </section> <section id="2" class="panel red"> <div class="text">SECTION 2</div> </section> <section id="3" class="panel gray"> <div class="text">SECTION 3</div> </section> <section id="4" class="panel red"> <div class="text">SECTION 4</div> <!-- 修正原文本错误:SECTION 2 → SECTION 4 --> </section> <script> // 获取所有区块和导航圆点元素 const sections = document.querySelectorAll('section'); const navSpans = document.querySelectorAll('.scroll-control span'); // 滚动监听:更新当前激活的导航圆点 function updateNavStatus() { // 计算滚动位置(加上视口高度一半,用来判断哪个区块处于视口核心区域) const scrollPosition = window.scrollY + window.innerHeight / 2; sections.forEach((section, index) => { const sectionTop = section.offsetTop; const sectionBottom = sectionTop + section.offsetHeight; // 当滚动位置落在当前区块范围内时,标记对应导航圆点为激活状态 if (scrollPosition >= sectionTop && scrollPosition < sectionBottom) { navSpans.forEach(span => span.classList.remove('current', 'inactive')); navSpans[index].classList.add('current'); // 给其他圆点添加非激活样式 navSpans.forEach((span, i) => { if (i !== index) span.classList.add('inactive'); }); } }); } // 导航圆点点击事件:平滑滚动到对应区块 navSpans.forEach((span, index) => { span.addEventListener('click', (e) => { e.preventDefault(); // 阻止默认锚点跳转行为 // 计算目标区块的滚动位置(区块在文档中的原始顶部偏移量) const targetScrollTop = sections[index].offsetTop; // 平滑滚动到目标位置 window.scrollTo({ top: targetScrollTop, behavior: 'smooth' }); }); }); // 页面初始化时执行一次,确保导航状态正确 updateNavStatus(); // 监听滚动事件,实时更新导航状态 window.addEventListener('scroll', updateNavStatus); </script> </body> </html>
关键逻辑说明
- CSS修正:调整了滚动行为的语法错误,修正了导航的居中方向,添加了过渡动画让样式变化更自然。
- 滚动监听逻辑:通过判断滚动位置落在哪个区块的文档范围内,来高亮对应导航圆点——因为sticky区块的
offsetTop是它在文档中的原始位置,滚动到这个位置时,目标区块会自动顶在视口顶部。 - 点击导航处理:阻止默认锚点跳转,手动计算并平滑滚动到目标区块的原始位置,确保精准切换。
这样调整后,你的导航圆点就能正常工作了:滚动时自动高亮当前显示的区块,点击圆点也能平滑跳转到对应内容。
备注:内容来源于stack exchange,提问作者Marielle Nadeau
相关产品推荐
相关产品推荐

