遇到一个小模块需要实现吸顶效果,在此简单总结一下:主要有2种思路:1.通过js代码监控需要吸顶的部分距离顶部的位置来设置固定定位;2.通过css的粘性定位属性来实现。
思路一详解:
1.div初始居普通文档流中
2. 给window添加scroll事件(可事件节流),获取div的offset的top值,滚动时scrollTop值和top比较,当到达top时给div添加一个fixed的class使其固定
3. 向上滚动时当到达div初始top时则删除fixed的class,此时div又回到普通文档流中
4. fixed样式非IE6浏览器使用position:fixed,IE6使用position:absolute和IE expression
代码实现:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>吸顶测试</title>
<style>
.top{
height: 1000px;
background-color: salmon;
}
.bottom{
height: 1000px;
background-color: seagreen;
}
#xidTop {
width: 100%;
height: 50px;
background: skyblue;
}
</style>
<script>
window.onload = function () {
var oDiv = document.getElementById('xidTop');
var divT = oDiv.offsetTop;
window.onscroll = function () {
// 获取当前页面的滚动条纵坐标位置 (依次为火狐谷歌、safari、IE678)
var scrollT = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;
if (scrollT >= divT) {
if (window.navigator.userAgent.indexOf('MSIE 6.0') != -1) {
// 兼容IE6代码
oDiv.style.position = 'absolute';
oDiv.style.top = scrollT + 'px';
oDiv.style.left = 0 + 'px';
} else {
// 正常浏览器代码
oDiv.style.position = 'fixed';
oDiv.style.top = 0;
oDiv.style.left = 0;
}
} else
oDiv.style.position = '';
}
}
</script>
</head>
<body>
<div>
<div class="top"></div>
<div id="xidTop">吸顶:主要实现当位置将要超过div初始top时,让其置顶。</div>
<div class="bottom"></div>
</div>
</body>
</html>
思路二详解:
使用 position:sticky
实现
1、粘性定位是什么?
粘性定位 sticky
相当于相对定位 relative
和固定定位 fixed
的结合;在页面元素滚动过程中,某个元素距离其父元素的距离达到 sticky
粘性定位的要求时;元素的相对定位 relative
效果变成固定定位 fixed
的效果。
MDN 传送门
2、如何使用?
使用条件:
- 父元素不能
overflow:hidden
或者overflow:auto
属性 - 必须指定
top、bottom、left、right
4 个值之一,否则只会处于相对定位 - 父元素的高度不能低于
sticky
元素的高度 -
sticky
元素仅在其父元素内生效
在需要滚动吸顶的元素加上以下样式便可以实现这个效果:
.sticky {
position: -webkit-sticky;
position: sticky;
top: 0;
}
复制代码
3、这个属性好用吗?
我们先看下在 Can I use 中看看这个属性的兼容性:
可以看出这个属性的兼容性并不是很好,因为这个 API 还只是实验性的属性。不过这个 API 在 IOS 系统的兼容性还是比较好的。
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.main{
position: relative;
}
.bottom{
width:100%;
height: 1000px;
background-color: yellow;
}
.head{
position: sticky;
top: 110px;
width: 100%;
height: 50px;
background-color: #2aabd2;
}
.top{
height: 1000px;
width:100%;
background-color: red;
}
</style>
</head>
<body>
<div class="main">
<div class="top"></div>
<div class="head">
吸顶部分
</div>
<div class="bottom"></div>
</div>
</body>
</html>
总结:
方式一
优点:避免兼容问题
缺点:高频触发引起的性能问题(可以通过防抖来优化一下下)
方式二:
缺点:新属性属于实验性阶段,兼容问题
优点:代码比较简洁(非要说的话)