什么是sticky?
这里的sticky,就是粘性定位或者粘性布局。
很多情况下,我们在滚动页面的过程中,期望某个元素在滚动到顶部时可以固定(或悬浮)在该位置,元素position表现为fixed。
两种方法
一、css方法,position:sticky
单词sticky的中文意思是“粘性的”,position:sticky表现也符合这个粘性的表现。基本上,可以看出是position:relative和position:fixed的结合体——当元素在屏幕内,表现为relative,就要滚出显示器屏幕的时候,表现为fixed。
示例:
<style>
.red{
position: -webkit-sticky;
position: sticky;
top: 0;
}
</style>
<body style="height: 2000px">
<div style="height: 800px;background-color: blue"></div>
<div class="red" style="height: 200px;background-color: red"></div>
<div style="height: 200px;margin-top:600px;background-color: black"></div>
</body>
运行上段代码,会出现如下两张图的结果。当红色区块滑动到页面顶部后固定在顶部。此时表现为fixed。
图一、红色区块滑动到顶部时,底部空白

图二、红色区块滑动到顶部后,页面继续下滑,出现黑色区块。红色区块此时表现为fixed。

sticky属性依赖于用户的滚动,在 position:relative 与 position:fixed 定位之间切换。元素定位表现为在跨越特定阈值前为相对定位,之后为固定定位。 sticky属性仅在以下几个条件都满足时有效:
- 父级元素不能有任何overflow:visible以外的overflow设置,否则没有粘滞效果。因为改变了滚动容器(即使没有出现滚动条)。因此,如果你的position:sticky无效,看看是不是某一个祖先元素设置了overflow:hidden,移除之即可。
- 父级元素设置和粘性定位元素等高的固定的height高度值,或者高度计算值和粘性定位元素高度一样,也没有粘滞效果。
- 同一个父容器中的sticky元素,如果定位值相等,则会重叠;如果属于不同父元素,且这些父元素正好紧密相连,则会鸠占鹊巢,挤开原来的元素,形成依次占位的效果。至于原因需要理解粘性定位的计算规则。
- sticky定位,不仅可以设置top,基于滚动容器上边缘定位;还可以设置bottom,也就是相对底部粘滞。如果是水平滚动,也可以设置left和right值。
这里有大佬更详细的讲解:www.zhangxinxu.com/wordpress/2…
二、js方法,利用getBoundingClientRect()和scrollTop()
getBoundingClientRect()方法:它返回一个对象,其中包含了left、right、top、bottom四个属性,分别对应了该元素的左上角和右下角相对于浏览器窗口(viewport)左上角的距离。
scrollTop()方法:返回或设置匹配元素的滚动条的垂直位置。当用于返回位置时,该方法返回第一个匹配元素的滚动条的垂直位置;当用于设置位置时,该方法设置所有匹配元素的滚动条的垂直位置。本文使用它返回第一个匹配的滚动条的垂直位置。
示例:
<head>
<meta charset="UTF-8">
<title>scroll</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.0/jquery.js" ></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<style>
.scroll_fixed{
position: fixed;
top: 0;
}
</style>
</head>
<body style="height: 2000px">
<div style="height: 1000px;background-color: blue"></div>
<div id="rect" class="scroll" style="width:200px;height: 200px;background-color: red"></div>
<div style="height: 200px;background-color: blueviolet;margin-top:600px"></div>
<script>
$(document).ready(function () {
let scroll = document.getElementById("rect");
let top = scroll.getBoundingClientRect().top;
//on() 添加监听"所要监听的事件",function(){}当监听到事件后执行的方法
$(window).on("scroll",function () {
//this代表window,$(this).scrollTop()返回窗口滚动条的垂直位置,也就是滚动条离页面顶部的绝对距离。
if($(this).scrollTop()>top){
$("#rect").addClass("scroll_fixed");
}
else{
$("#rect").removeClass("scroll_fixed");
}
})
})
</script>
</body>
运行上段代码,监听页面的滑动事件,当页面向下滑动时,窗口滚动条的垂直位置大于红色区块相对于视角窗口上方的距离时,调用addClass()方法给该ID为"rect"的元素(即红色区块)添加类scroll_fixed{position: fixed;top:0;},使得红色区块此时固定在页面顶部。反之,当页面向上滑动时,窗口滚动条的垂直位置小于红色区块相对于视角窗口上方的距离时,调用removeClass()方法移除该元素的类{position: fixed;top:0;},元素回复原有position状态。
结果如下图: 图一、红色区块滑动到顶部时,底部空白图二、红色区块滑动到顶部后,页面继续下滑,出现紫色区块。红色区块此时表现为fixed。

