You need to enable JavaScript to run this app. Bootstrap 5结合vanilla JS实现滚动时第二个导航栏吸顶固定
优惠活动
大模型
产品
解决方案
定价
更多

Bootstrap 5结合vanilla JS实现滚动时第二个导航栏吸顶固定

主导航栏滚动吸顶的纯JS实现方案

核心实现逻辑无冗余依赖,直接覆盖双导航结构的常见场景,同时规避布局跳动、滚动卡顿、状态失效等常见问题:

  • 提前计算主导航栏相对于文档顶部的原始偏移位置,不在滚动过程中重复读取易变动的定位值
  • 监听页面滚动行为,当垂直滚动距离达到导航原始偏移值时,给导航添加固定定位类实现视口顶部吸附
  • 补偿固定定位带来的文档流高度差,避免导航吸顶瞬间下方内容跳动
  • 对高频触发的滚动事件做节流处理,降低性能消耗

参考结构适配

对应双导航的页面结构,DOM布局逻辑如下:

<!-- 第一导航:顶部联系信息栏 -->
<div class="contact-bar">
  <span>服务热线:400-xxx</span>
</div>
<!-- 第二导航:需要实现吸顶的主导航栏 -->
<nav class="main-nav">
  <a href="/">首页</a>
  <a href="/product">产品</a>
  <a href="/contact">联系我们</a>
</nav>
<!-- 页面主体内容 -->
<main class="page-content">
  <!-- 页面正文内容 -->
</main>

基础样式配置

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
.contact-bar {
  height: 40px;
  background: #f0f2f5;
}
.main-nav {
  height: 60px;
  background: #ffffff;
  transition: top 0.2s ease;
}
/* 吸顶状态样式 */
.main-nav.nav-fixed {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  z-index: 999;
}
.page-content {
  padding-top: 24px;
}
/* 吸顶时的内容高度补偿,抵消导航脱离文档流的高度差 */
.page-content.content-fixed {
  padding-top: calc(24px + 60px);
}

纯JS交互实现

// 缓存DOM元素
const mainNav = document.querySelector('.main-nav');
const pageContent = document.querySelector('.page-content');
// 存储主导航的原始顶部偏移值,初始加载时计算
let navOffsetTop = mainNav.offsetTop;
let scrollTimer = null;

// 吸顶状态判断逻辑
function updateNavStickyState() {
  // 获取当前页面垂直滚动距离
  const currentScrollY = window.scrollY || document.documentElement.scrollTop;
  if (currentScrollY >= navOffsetTop) {
    mainNav.classList.add('nav-fixed');
    pageContent.classList.add('content-fixed');
  } else {
    mainNav.classList.remove('nav-fixed');
    pageContent.classList.remove('content-fixed');
  }
}

// 绑定滚动事件,加10ms节流避免高频计算卡顿
window.addEventListener('scroll', () => {
  if (scrollTimer) clearTimeout(scrollTimer);
  scrollTimer = setTimeout(updateNavStickyState, 10);
});

// 页面加载完成时主动执行一次判断,处理刷新时已经处于吸顶位置的场景
window.addEventListener('load', updateNavStickyState);

// 窗口尺寸变化时重新计算导航偏移值,适配响应式布局下的高度变化
window.addEventListener('resize', () => {
  // 先移除固定定位状态再计算原始偏移,避免被fixed定位干扰计算结果
  mainNav.classList.remove('nav-fixed');
  pageContent.classList.remove('content-fixed');
  navOffsetTop = mainNav.offsetTop;
  updateNavStickyState();
});

注意事项

  • 不要在滚动事件内实时读取导航的offsetTop值:导航变为固定定位后,自身的offsetTop会变为0,会导致吸顶触发逻辑完全失效
  • 如果不需要兼容IE等老旧浏览器,直接给主导航元素设置 position: sticky; top: 0; 即可实现同等效果,无需额外JS,性能更优。注意sticky定位会受父元素overflow: hidden属性影响导致失效,使用时需排除这类干扰
  • 必须处理固定定位带来的文档流高度差,否则导航吸顶瞬间下方内容会向上跳动一个导航的高度,影响视觉体验

内容的提问来源于stack exchange,提问作者jhon-jhones

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.05 15:36:03