如何实现滚动时导航栏下方的线条动画效果?
滚动时导航栏下方线条动画的实现方法
核心思路是监听页面滚动事件,动态匹配当前可视区域对应的导航项,结合CSS过渡动画,让导航栏下方的线条平滑切换位置和宽度。以下是具体实现代码:
1. HTML结构
先搭建导航栏和测试用的内容区块,同时添加用于动画的线条元素:
<nav class="navbar"> <ul class="nav-links"> <li><a href="#section1" class="nav-link active">首页</a></li> <li><a href="#section2" class="nav-link">关于</a></li> <li><a href="#section3" class="nav-link">服务</a></li> <li><a href="#section4" class="nav-link">联系</a></li> </ul> <span class="nav-indicator"></span> </nav> <section id="section1" class="section">首页内容</section> <section id="section2" class="section">关于内容</section> <section id="section3" class="section">服务内容</section> <section id="section4" class="section">联系内容</section>
2. CSS样式
设置导航栏布局,定义线条的初始样式和过渡动画:
.navbar { position: fixed; top: 0; width: 100%; background: #fff; padding: 1rem 0; box-shadow: 0 2px 4px rgba(0,0,0,0.1); } .nav-links { list-style: none; display: flex; justify-content: center; gap: 2rem; margin: 0; padding: 0; position: relative; } .nav-link { text-decoration: none; color: #333; font-weight: 500; padding: 0.5rem 0; } /* 动画线条核心样式 */ .nav-indicator { position: absolute; bottom: 0; left: 0; height: 3px; background: #2563eb; border-radius: 2px; transition: all 0.3s ease; /* 平滑过渡动画 */ } /* 测试用内容区块样式 */ .section { height: 100vh; display: flex; align-items: center; justify-content: center; font-size: 2rem; } #section2 { background: #f3f4f6; } #section3 { background: #e5e7eb; } #section4 { background: #d1d5db; }
3. JavaScript逻辑
监听滚动事件,判断当前激活的导航项,实时更新线条的位置和宽度:
const navLinks = document.querySelectorAll('.nav-link'); const navIndicator = document.querySelector('.nav-indicator'); // 设置线条位置和宽度的函数 function setIndicator() { const activeLink = document.querySelector('.nav-link.active'); if (!activeLink) return; const linkRect = activeLink.getBoundingClientRect(); const navRect = document.querySelector('.nav-links').getBoundingClientRect(); navIndicator.style.left = `${linkRect.left - navRect.left}px`; navIndicator.style.width = `${linkRect.width}px`; } // 滚动时更新激活状态和线条 window.addEventListener('scroll', () => { let currentSectionId = ''; document.querySelectorAll('.section').forEach(section => { const sectionTop = section.offsetTop; if (window.scrollY >= sectionTop - 100) { currentSectionId = section.getAttribute('id'); } }); // 更新导航链接的active状态 navLinks.forEach(link => { link.classList.remove('active'); if (link.getAttribute('href') === `#${currentSectionId}`) { link.classList.add('active'); } }); setIndicator(); }); // 页面加载初始化线条位置 window.addEventListener('load', setIndicator); // 点击导航链接后同步更新线条 navLinks.forEach(link => { link.addEventListener('click', () => { setTimeout(setIndicator, 100); }); });
关键要点
- CSS过渡:通过
transition属性让线条的位置和宽度变化产生平滑动画效果,避免生硬切换。 - 滚动监听:通过判断滚动距离与各内容区块的顶部位置,确定当前应激活的导航项。
- 动态计算:使用
getBoundingClientRect()获取元素的位置和尺寸数据,精准控制线条的显示位置。
内容的提问来源于stack exchange,提问作者Awais Dev
相关产品推荐
相关产品推荐

