实现非同父级blue-div滚动时固定在red-div底部(含头部显隐)
实现滚动时导航栏隐藏/显示 + 跨父元素固定子元素的交互效果
核心需求
- 红色导航栏(red-div):向下滚动时隐藏,向上滚动时重新显示
- 蓝色栏(blue-div):滚动到对应位置后固定在红色导航栏底部,二者不属于同一父元素
完整代码实现
HTML
<nav class="red-div"></nav> <div class="green-div"> <div class="test2"></div> <div class="blue-div"></div> </div>
CSS
* { margin: 0; padding: 0; box-sizing: border-box; } .red-div { background-color: red; width: 100%; height: 50px; position: sticky; top: 0; transition: transform 0.3s ease; z-index: 100; } .red-div.hidden { transform: translateY(-100%); } .green-div { background-color: green; width: 100%; height: 1000px; } .test2 { width: 100%; height: 100px; } .blue-div { background-color: blue; width: 100%; height: 30px; transition: top 0.3s ease; } .blue-div.fixed { position: fixed; left: 0; right: 0; z-index: 99; }
JavaScript
const redDiv = document.querySelector('.red-div'); const blueDiv = document.querySelector('.blue-div'); const redDivHeight = redDiv.offsetHeight; // 计算blue-div开始固定的滚动阈值:自身初始位置减去导航栏高度 const blueFixThreshold = blueDiv.offsetTop - redDivHeight; let lastScrollTop = 0; window.addEventListener('scroll', () => { const currentScrollTop = window.pageYOffset || document.documentElement.scrollTop; // 控制导航栏显示/隐藏 if (currentScrollTop > lastScrollTop) { redDiv.classList.add('hidden'); } else { redDiv.classList.remove('hidden'); } // 控制blue-div固定位置 if (currentScrollTop >= blueFixThreshold) { blueDiv.classList.add('fixed'); // 根据导航栏状态动态调整top值 blueDiv.style.top = redDiv.classList.contains('hidden') ? '0' : `${redDivHeight}px`; } else { blueDiv.classList.remove('fixed'); blueDiv.style.top = ''; } lastScrollTop = currentScrollTop; });
关键逻辑说明
导航栏滚动交互:
- 通过对比当前滚动位置与上一次滚动位置,判断滚动方向
- 使用CSS
transform: translateY(-100%)实现导航栏隐藏,配合过渡动画保证平滑效果
blue-div固定逻辑:
- 提前计算触发固定的滚动阈值,确保blue-div到达导航栏底部位置时开始固定
- 固定时根据导航栏的显示状态动态调整
top值:导航显示时固定在其底部,导航隐藏时固定在视口顶部 - 滚动回阈值以下时,移除固定类,恢复元素原有布局
内容的提问来源于stack exchange,提问作者sghaier saif eddine
相关产品推荐
相关产品推荐

