吸顶效果:1.css属性sticky优缺点 2.简单js实现吸顶效果
1.css属性position:sticky
使用这个属性可以很方便的实现吸顶效果,并且只需要一行css
position: sticky
原理:
粘性元素根据滚动位置在相对(relative)和固定(fixed)之间切换。起先它会被相对定位,直到在视口中遇到给定的偏移位置为止 - 然后将其“粘贴”在适当的位置(比如 position:fixed。
兼容性
简单的同时,也意味着兼容性会差上一些,我简单总结一下:
- 浏览器兼容问题,IE/Edge 15 以及更早的版本不支持粘性定位,或者一些低版本的其他浏览器也不支持。
- 父元素不能设置overflow:visible 以外的其他值,比如scroll和auto均不能,overflow-x和overflow-y同理。
- 父元素不能给固定高度等于粘性定位元素,或者父元素计算高度等于粘性定位元素。
- 必须给粘性定位元素设置一个定位值,如top或者bottom。
举个具体例子,下面随便写了个小demo:
<style>
.wrapper {
height: 800px;
}
.tab {
margin-left: 50px;
margin-top: 100px;
/*核心设置*/
position: sticky;
width: 200px;
height: 300px;
/* 一定要设置top或者bottom,否则粘性定位效果失效,参考我写的原理自然明白原因了,看不懂 打死嗷 */
top: 0;
background-color: #eee;
box-shadow: 1px 1px 5px #ccc;
border-radius: 10px;
display: flex;
flex-direction: column;
}
.tab div {
width: 100%;
height: 60px;
border-top: 1px solid #aaa;
text-align: center;
line-height: 50px;
cursor: pointer;
}
.tab div:first-child {
border-top: none;
}
</style>
</head>
<body>
<div class="wrapper">
<div class="tab">
<div>tab1</div>
<div>tab2</div>
<div>tab3</div>
<div>tab4</div>
<div>tab5</div>
<div>tab6</div>
</div>
</div>
</body>
看下效果吧:
1)当没有吸顶时:position相当于relative(会占位)
2)粘性生效时,position相当于fixed,此时top属性发生作用。
2. 简单js实现吸顶效果
原理走一波:
1)计算元素距离窗口的高度 element.offsetTop
(小细节:offsetTop计算的是当前元素距离父元素顶部的高度,多层嵌套则需要递归叠加offsetTop,所以建议是选取最外面的那层元素,则可以直接获取距离窗口的高度)
2)计算页面滚动高度
document.documentElement.scrollTop || document.body.scrollTop;
(为什么这么写? document.documentElement.scrollTop 有些移动端不支持,导致无法获取正确的滚动高度,使用document.body.scrollTop移动端也能正常获取,兼容一下)
3)监听滚动事件并进行判断
初始定位为 'relative’或者干脆不设置。当页面滚动高度超过元素距离窗口的高度,设置为fixed,且top为0(当然bottom也可以,数值随便设)
上代码:
html部分
<div class="wrapper">
<div class="tab" id="scroll-tab">
<div>tab1</div>
<div>tab2</div>
<div>tab3</div>
<div>tab4</div>
<div>tab5</div>
<div>tab6</div>
</div>
</div>
css部分
.wrapper {
height: 800px;
}
/* 核心设置 */
#scroll-tab[data-fixed="fixed"] {
position: fixed;
top: 0;
margin-top: 0;
}
.tab {
margin-left: 50px;
margin-top: 100px;
width: 200px;
height: 300px;
background-color: #eee;
box-shadow: 1px 1px 5px #ccc;
border-radius: 10px;
display: flex;
flex-direction: column;
}
.tab div {
width: 100%;
height: 60px;
border-top: 1px solid #aaa;
text-align: center;
line-height: 50px;
cursor: pointer;
}
.tab div:first-child {
border-top: none;
}
js部分
const wrapperElem = document.getElementById("scroll-tab");
//1) 计算高度
const topY = wrapperElem.offsetTop;
//3) 监听滚动事件并进行判断
document.onscroll = function () {
//2) 计算滚动距离
const scrollY =
document.documentElement.scrollTop || document.body.scrollTop;
console.log(scrollY);
console.log(scrollY >= topY);
//自定义属性结合css属性选择器控制position、top、margin等属性
wrapperElem.setAttribute("data-fixed", scrollY >= topY ? "fixed" : "");
};
结构基本一致,实现方法不一样,使用js写法几乎没有兼容性问题,是比较推荐的方案。
有帮助的话,可以给个免费的赞或者关注,3Q啦~
参考文章:
https://segmentfault.com/a/1190000010708191
https://www.cnblogs.com/coco1s/p/14180476.html
https://www.zhangxinxu.com/wordpress/2018/12/css-position-sticky/