JavaScript实现多个导航标题吸顶效果

作者:窗边听雨

时间:2026-10-23

浏览:78

本文详解如何利用JavaScript实现多个导航标题的吸顶效果。通过监听window滚动事件,结合offsetTop计算每个标题的可视范围,并处理最后一个标题的特殊边界情况,确保在PC端和移动端滑动时,当前区域标题能正确固定于顶部,提升用户体验。

文章目录

多标题吸顶需求分析

针对导航栏的吸顶功能,PC端与移动端的需求存在差异。PC端通常只需单个顶部导航固定,而移动端在页面滑动时,往往需要实现多个标题的依次吸顶,例如地区选择列表中省份标题的固定显示。

单个标题吸顶与多个标题吸顶的核心区别在于作用域的控制。多标题吸顶需划定一个高度区间,在该区间内仅允许一个标题处于吸顶状态,其余标题保持固定定位或其他样式。

页面布局与样式设置

一、页面布局及样式

为测试效果,此处使用了多个重复的section标签。实际开发中,请根据具体需求调整布局结构和CSS样式。


<body>
 <ul id="container">
 <h1>实现多个标题的吸顶</h1>
 <section>
  <div class="box">header1</div>
  <li>1</li>
  <li>1</li>
  <li>1</li>
  <li>1</li>
  <li>1</li>
  <li>1</li>
 </section>
 
 <!--设置多个如header1的子列表,窗口可以进行滚动,此处省略-->
 
 <section>
  <div class="box">header5</div>
  <li>1</li>
  <li>1</li>
  <li>1</li>
  <li>1</li>
  <li>1</li>
  <li>1</li>
 </section>
 
 </ul>
</body>

<style type="text/css">
 * {
 padding: 0;
 margin: 0;
 }
 ul {
 width: 100%;
 }
 li {
 width: 200px;
 color: white;
 margin: 10px;
 list-style: none;
 border-radius: 5px;
 border: 1px solid #191970;
 background: #4169E1;
 text-align: center;
 }
 div {
 width: 100%;
 height: 30px;
 color: white;
 padding-left: 20px;
 background: #DC143C;
 }
 .box1 {
 position: fixed;
 top: 0;
 }
</style>

JavaScript核心逻辑实现

二、JS的编写

第一步,获取所有需要执行吸顶操作的标题元素。建议这些标题使用统一的布局和样式,以便更高效、统一地获取和处理。


var box = document.getElementsByClassName('box'), //获取所有需要吸顶效果的标题
  section = document.getElementsByTagName('section'); //获取所有子列表,后面有用

第二步,统计标题数量并定义一个数组,用于存储每个标题距离父元素的垂直偏移量(offsetTop)。


var ot = [],  //存储每个标题的offsetTop
  len = box.length;   //标题的个数

第三步,遍历所有标题元素,计算并获取其offsetTop值,将这些值存入上述数组中。


for(let i=0; i<len; i++) {
 ot.push(box[i].offsetTop);  //获取每个标题的offsetTop
}

第四步,监听window的滚动事件,获取当前滚动高度scrollTop。若滚动高度位于第i个标题的offsetTop与第i+1个标题的offsetTop之间(例如滚动高度处于header1和header2的offsetTop之间,此时header1吸顶),则为第i个标题添加box1样式,从而实现吸顶效果。


window.onscroll = function () {
 //获取滚动的高度
 var st = document.documentElement.scrollTop || document.body.scrollTop;
 
 for(let i=0; i<len; i++) {
 if(st>ot[i] && st<ot[i+1]) { //滚动时监听位置,为标题的吸顶设置一个现实范围
  box[i].className = 'box box1';
 } else {
  box[i].className = 'box';
 }
 
 }
}

第五步,上述逻辑存在一个潜在问题:当滚动至最后一个标题(即索引为i)时,无法获取第i+1个标题的offsetTop值,导致判断逻辑失效。

解决方案:从第一步获取的section标签集合中取出最后一个子列表(section[0]),计算该子列表的高度,进而推算出最后一个标题的有效显示高度范围,并将此范围值存入ot数组中,以完善边界判断。


//获取最后一个子列表的高度,为了设置最后一个吸顶标题的位置
//section[len-1].getBoundingClientRect().height
//此方法返回一个number
 
ot.push(box[len-1].offsetTop + section[len-1].getBoundingClientRect().height);

效果展示与完整代码

三、最后效果

多标题吸顶需求分析

多标题吸顶需求分析

完整js代码


var box = document.getElementsByClassName('box'), //获取所有需要吸顶效果的标题
 section = document.getElementsByTagName('section'); //获取所有子列表
 
var ot = [],       //存储每个标题的offsetTop
 len = box.length;   //标题的个数
 
for(let i=0; i<len; i++) {
 ot.push(box[i].offsetTop);  //获取每个标题的offsetTop
}
 
//获取最后一个子列表的高度,为了设置最后一个吸顶标题的位置
//section[len-1].getBoundingClientRect().height
//此方法返回一个number
 
ot.push(box[len-1].offsetTop + section[len-1].getBoundingClientRect().height);
 
window.onscroll = function () {
 //获取滚动的高度
 var st = document.documentElement.scrollTop || document.body.scrollTop;
 
 for(let i=0; i<len; i++) {
 if(st>ot[i] && st<ot[i+1]) { //滚动时监听位置,为标题的吸顶设置一个现实范围
  box[i].className = 'box box1';
 } else {
  box[i].className = 'box';
 }
 
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章