js实现多个标题吸顶效果


Posted in Javascript onJanuary 08, 2020

对于导航的吸顶效果,pc端和移动端的需求可能有些差异。在pc端,我们通常只需要一个顶部导航;在移动端,在滑动页面的时候,更需要多个标题的吸顶(例如地区的选择,需要将省份吸顶)。

单个标题吸顶和多个标题吸顶的区别在于:多个标题吸顶需要确定一个高度范围,在这个范围中只能有一个标题吸顶,其他都是固定效果。

一、页面布局及样式

此处为了测试效果,用了几个重复的section标签,大家根据实际需求编写布局和样式。

<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>

二、js的编写

1、获取所有需要吸顶效果的标题。这里的标题最好用相同的布局和样式,获取时能够更快捷和统一。

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

2、获取标题个数和定义一个数组,用来存放每个标题到父元素的距离(offsetTop)。

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

3、遍历所有标题,获取offsetTop,并存入ot数组中。

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

4、监听window的滚动事件,获取scrollTop;如果滚动高度位于第i个标题的offsetTop和第i+1个标题的offsetTop之间(例如滚动的高度位于header1和header2的offsetTop之间,heade1吸顶),则第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';
 }
 
 }
}

5、第四步中,有个问题:当滚动道最后一个标题(i)时,无法获取(i+1)。

解决方法:从第一步中获得的section标签集合中拿出最后一个子列表(section[0]),然后获取最后一个子列表的高度,计算出最后一个标题的显示高度范围,并存入ot数组中。

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

三、最后效果

js实现多个标题吸顶效果

js实现多个标题吸顶效果

完整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';
 }
 
 }
}

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

Javascript 相关文章推荐
Javascript 继承机制的实现
Aug 12 Javascript
jcrop基本参数一览
Jul 16 Javascript
document.documentElement和document.body区别介绍
Sep 16 Javascript
JavaScript四种调用模式和this示例介绍
Jan 02 Javascript
Array栈方法和队列方法的特点说明
Jan 24 Javascript
如何实现chrome浏览器关闭页面时弹出“确定要离开此面吗?”
Mar 05 Javascript
JavaScript设置表单上传时文件个数的方法
Aug 11 Javascript
js随机生成26个大小写字母
Feb 12 Javascript
详解Vue路由开启keep-alive时的注意点
Jun 20 Javascript
微信小程序可滑动月日历组件使用详解
Oct 21 Javascript
一篇文章带你浅入webpack的DLL优化打包
Feb 20 Javascript
JavaScript进阶(二)词法作用域与作用域链实例分析
May 09 Javascript
Vue v-model组件封装(类似弹窗组件)
Jan 08 #Javascript
jquery实现吸顶导航效果
Jan 08 #jQuery
JS实现网站吸顶条
Jan 08 #Javascript
js实现移动端吸顶效果
Jan 08 #Javascript
vue.js自定义组件实现v-model双向数据绑定的示例代码
Jan 08 #Javascript
微信小程序实现吸顶效果
Jan 08 #Javascript
JS实现吸顶特效
Jan 08 #Javascript
You might like
配置最新的PHP加MYSQL服务器
2006/10/09 PHP
判断是否为指定长度内字符串的php函数
2010/02/16 PHP
PHP生成图片验证码、点击切换实例
2014/06/25 PHP
非常实用的php验证码类
2016/05/15 PHP
在线编辑器中换行与内容自动提取
2009/04/24 Javascript
asp(javascript)全角半角转换代码 dbc2sbc
2009/08/06 Javascript
了解Javascript的模块化开发
2015/03/02 Javascript
简单的分页代码js实现
2016/05/17 Javascript
jQuery实现输入框邮箱内容自动补全与上下翻动显示效果【附demo源码下载】
2016/09/20 Javascript
Vue axios全局拦截 get请求、post请求、配置请求的实例代码
2018/11/28 Javascript
Layui Form 自定义验证的实例代码
2019/09/14 Javascript
NodeJS http模块用法示例【创建web服务器/客户端】
2019/11/05 NodeJs
详解vue-template-admin三级路由无法缓存的解决方案
2020/03/10 Javascript
[01:25:09]2014 DOTA2国际邀请赛中国区预选赛 5 23 CIS VS DT第二场
2014/05/24 DOTA
[05:16]《大圣!大圣》——DOTA2新英雄齐天大圣配音李世宏老师专访
2016/12/13 DOTA
Python实现的数据结构与算法之队列详解
2015/04/22 Python
python之Socket网络编程详解
2016/09/29 Python
举例讲解Python常用模块
2019/03/08 Python
Python异常原理及异常捕捉实现过程解析
2020/03/25 Python
Python urllib request模块发送请求实现过程解析
2020/12/10 Python
中科创达面试题
2016/12/28 面试题
自主实习接收函
2014/01/13 职场文书
医学专业职业生涯规划范文
2014/02/05 职场文书
师范生自荐信模板
2014/05/28 职场文书
模具设计与制造专业自荐书
2014/07/01 职场文书
男性健康日的活动方案
2014/08/18 职场文书
承租经营合作者协议书
2014/10/01 职场文书
2014年中职班主任工作总结
2014/12/16 职场文书
毕业设计致谢词
2015/05/14 职场文书
2015年测量员工作总结
2015/05/23 职场文书
小学体育教学随笔
2015/08/14 职场文书
2016党风廉政建设心得体会范文
2016/01/25 职场文书
2019开业庆典剪彩仪式主持词!
2019/07/22 职场文书
如何使用JavaScript策略模式校验表单
2021/04/29 Javascript
HTML+css盒子模型案例(圆,半圆等)“border-radius” 简单易上手
2021/05/10 HTML / CSS
Redis基本数据类型哈希Hash常用操作命令
2022/06/01 Redis