滚动过100vh高度的头部后用JavaScript实现导航栏固定的问题(保留min-height属性)
滚动过100vh高度的头部后用JavaScript实现导航栏固定的问题(保留min-height属性)
嘿,我看了你的代码,发现几个可能导致导航栏固定不生效的小问题,咱们一起来修复它,同时保留你想要的min-height:100vh属性:
问题分析
- 导航栏固定后的样式缺失:你的
.fixed类只加了基础定位属性,但没设置宽度和原有的内边距,导致固定后导航栏布局错乱,看起来像是没生效。 - 初始化未检查滚动位置:如果用户刷新页面时已经滚动过头部区域,导航栏不会自动加上固定类,体验不够完善。
- 滚动事件无节流(可选优化):频繁触发scroll事件可能影响页面性能,加上节流能让代码更高效。
修复后的代码
JavaScript 部分
document.addEventListener('DOMContentLoaded', function() { const nav = document.getElementById('mainNav'); const header = document.querySelector('.header'); let ticking = false; // 节流标记 function handleScroll() { if (!ticking) { window.requestAnimationFrame(function() { const headerHeight = header.offsetHeight; const scrollPosition = window.scrollY; if (scrollPosition > headerHeight) { nav.classList.add('fixed'); // 给body加padding,避免内容被固定导航栏遮挡 document.body.style.paddingTop = `${nav.offsetHeight}px`; } else { nav.classList.remove('fixed'); document.body.style.paddingTop = '0'; } ticking = false; }); ticking = true; } } // 初始化时先检查一次滚动位置,避免刷新页面时状态错误 handleScroll(); window.addEventListener('scroll', handleScroll); });
CSS 部分
修改.nav.fixed的样式,补充必要属性并添加过渡效果:
.header { min-height: 100vh; width: 100%; background-image: linear-gradient(rgba(4, 9, 30, 0.7), rgba(4, 9, 30, 0.7)), url('img/background-main.jpg'); background-position: center; background-size: cover; text-align: center; color: #fff; position: relative; } nav { display: flex; padding: 2% 6%; justify-content: space-between; align-items: center; z-index: 1000; transition: all 0.3s ease; /* 添加上下固定的平滑过渡 */ } nav.fixed { position: fixed; top: 0; left: 0; z-index: 1001; width: 100%; /* 确保导航栏占满页面宽度 */ padding: 2% 6%; /* 保留原有的内边距,维持布局一致 */ background-color: rgba(4, 9, 30, 0.95); /* 添加背景色,避免滚动后下方内容透出 */ } /* 其余原有CSS样式保持不变 */ nav img { width: 200px; } .nav-links { flex: 1; text-align: right; } .nav-links ul li { list-style: none; display: inline-block; padding: 8px 12px; position: relative; } .nav-links ul li a { color: #fff; text-decoration: none; font-size: 16px; font-weight: bold; } .nav-links ul li::after { content: ''; width: 0%; height: 2px; background: #1b99ca; display: block; margin: auto; transition: 0.5s; } .nav-links ul li:hover::after { width: 100%; } .nav-links ul li:hover>ul.dropdown { display: block; } ul li ul.dropdown { position: absolute; top: 100%; left: 0; background-color: rgba(41, 145, 255, 0.425); z-index: 999; display: none; min-width: 130px; border-radius: 5px; box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.2); } ul li ul.dropdown li { display: block; padding: 10px; } ul li ul.dropdown li a { color: #fff; text-decoration: none; display: block; font-size: 14px; font-weight: 600; transition: 0.3s; text-align: left; } ul li ul.dropdown li:hover { background: #003580; } .text-box { width: 90%; color: #fff; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); text-align: center; } .text-box h1 { font-size: 62px; } .text-box p { margin: 10px 0 40px; font-size: 14px; color: #fff; } .hero-btn { display: inline-block; text-decoration: none; color: #fff; border: 1px solid #fff; padding: 12px 34px; font-size: 13px; background: transparent; position: relative; cursor: pointer; transition: 0.6s; margin-top: 15px; border-radius: 5px; } .hero-btn:hover { background-color: #1b99ca; border: 1px solid #1b99ca; transition: 1s; } nav .fa { display: none; } nav .fa-bars { font-size: 25px; }
HTML 部分
你的原有HTML结构已经正确匹配了JS和CSS的选择器,无需修改:
<link href="https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet"> <link rel="stylesheet" href="index.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css" integrity="sha512-Evv84Mr4kqVGRNSgIGL/F/aIDqQb7xQ2vcrdIwxfjThSH8CSR7PBEakCr51Ck+w+/U6swU2Im1vVX0SVk9ABhg==" crossorigin="anonymous" referrerpolicy="no-referrer"> <section class="header"> <nav id="mainNav" class="mainNav"> <div class="logo"> <a href="index.html"> <img src="img/logo-padrao.png" alt="logo da JL Marine"></a> </div> <div class="nav-links" id="navLinks"> <i class="fa fa-times" onclick="hideMenu()"></i> <ul class="ul"> <li><a href="index.html">Início</a></li> <li> <a href="#">Sobre</a> <ul class="dropdown"> <li><a href="sobre.html">A Empresa</a></li> <li><a href="equipe.html">Equipe</a></li> </ul> </li> <li> <a href="services/services.html">Serviços</a> <ul class="dropdown"> <li><a href="services/marine.html">Marine</a></li> <li><a href="services/log.html">Logística</a></li> <li><a href="services/desp-adua.html">Despacho Aduaneiro</a></li> <li><a href="services/comex.html">Comex</a></li> <li><a href="services/outros.html">Outros</a></li> </ul> </li> <li><a href="contacts.html">Contato</a></li> </ul> </div> <i class="fa fa-bars" onclick="showMenu()"></i> </nav> <div class="text-box"> <h1>Conheça a JL Marine!</h1> <p>Confiabilidade & Excelência</p> <a href="sobre.html" class="hero-btn">Saiba Mais</a> </div> </section>
为什么这么改?
- 补充固定导航栏样式:
width:100%和原padding保证固定后布局和原来一致;添加背景色是因为固定后导航栏脱离了原header的背景,需要自己加背景才能遮住下方内容。 - 初始化检查滚动位置:页面刷新时如果已经滚动过头部,导航栏会自动固定,避免状态错误。
- 节流优化:用
requestAnimationFrame减少scroll事件触发频率,提升页面性能。 - body padding:导航栏固定后脱离文档流,下方内容会往上跳,添加对应高度的padding能避免内容被遮挡。
你可以试试这个修改后的代码,应该就能实现你想要的效果啦!
备注:内容来源于stack exchange,提问作者yCafEe
相关产品推荐
相关产品推荐

