实现TabBar联动滚动:单列展示页面,点击/滚动同步切换激活状态
实现滚动同步TabBar与点击跳转功能
核心实现逻辑
- 监听页面滚动,判断当前视口内的目标区块,同步更新TabBar的活跃状态
- 监听TabBar点击事件,触发对应区块的平滑滚动
完整示例代码
HTML 结构
<!-- 固定顶部的TabBar --> <div class="tab-bar"> <button class="tab active" data-tab="tab1">页面1</button> <button class="tab" data-tab="tab2">页面2</button> <button class="tab" data-tab="tab3">页面3</button> <button class="tab" data-tab="tab4">页面4</button> </div> <!-- 单列排列的页面区块 --> <div class="page-container"> <section id="tab1" class="page-section">页面1内容</section> <section id="tab2" class="page-section">页面2内容</section> <section id="tab3" class="page-section">页面3内容</section> <section id="tab4" class="page-section">页面4内容</section> </div>
CSS 样式
* { margin: 0; padding: 0; box-sizing: border-box; } /* TabBar样式:固定顶部,阴影区分层级 */ .tab-bar { position: fixed; top: 0; left: 0; width: 100%; display: flex; background: #fff; box-shadow: 0 2px 4px rgba(0,0,0,0.1); z-index: 100; } .tab { flex: 1; padding: 1rem; border: none; background: transparent; font-size: 1rem; cursor: pointer; transition: background-color 0.3s; } /* 活跃Tab的高亮样式 */ .tab.active { background-color: #e0e0e0; font-weight: bold; } /* 页面容器:避开固定TabBar的高度 */ .page-container { margin-top: 56px; } /* 每个页面区块占满视口高度,方便滚动测试 */ .page-section { height: 100vh; display: flex; align-items: center; justify-content: center; font-size: 2rem; } /* 区分不同页面区块的背景色 */ #tab1 { background-color: #f5f5f5; } #tab2 { background-color: #e8f5e9; } #tab3 { background-color: #e3f2fd; } #tab4 { background-color: #fff3e0; }
JavaScript 逻辑
// 获取所有Tab按钮和页面区块 const tabs = document.querySelectorAll('.tab'); const sections = document.querySelectorAll('.page-section'); const tabBarHeight = document.querySelector('.tab-bar').offsetHeight; // 滚动监听:同步Tab活跃状态 window.addEventListener('scroll', () => { const scrollTop = window.scrollY; let activeTabId = ''; sections.forEach(section => { const sectionTop = section.offsetTop - tabBarHeight; const sectionBottom = sectionTop + section.offsetHeight; // 判断当前滚动位置是否落在该区块范围内 if (scrollTop >= sectionTop && scrollTop < sectionBottom) { activeTabId = section.id; } }); // 更新Tab的活跃状态 tabs.forEach(tab => { tab.classList.toggle('active', tab.dataset.tab === activeTabId); }); }); // 点击监听:平滑滚动到对应区块 tabs.forEach(tab => { tab.addEventListener('click', () => { const targetSection = document.getElementById(tab.dataset.tab); const targetTop = targetSection.offsetTop - tabBarHeight; // 触发平滑滚动 window.scrollTo({ top: targetTop, behavior: 'smooth' }); }); });
关键细节说明
- 滚动判断时减去TabBar高度,避免TabBar遮挡区块顶部导致的状态判断错误
- 使用
data-tab属性关联Tab和对应区块,无需硬编码ID,代码扩展性更强 - 平滑滚动通过
scrollTo的behavior: 'smooth'实现,无需额外插件
内容的提问来源于stack exchange,提问作者farhan khan
相关产品推荐
相关产品推荐

