最近遇到一个需求中有个实现吸顶效果,即页面滚动到顶部,某元素固定到底部,离开顶部后回到原位置。
第一反应就是position: sticky;毕竟之前使用过,感觉效果很好,本以为一个sticky就可以大功告成,可现实啪啪打脸呐,一查才知sticky使用有诸多条件。先来看看position:sticky 是什么
一. position:sticky
基于用户的滚动位置来定位。粘性定位的元素是依赖于用户的滚动,在 position:relative 与 position:fixed 定位之间切换。
它的行为就像 position:relative; 而当页面滚动超出目标区域时,它的表现就像 position:fixed; ,它会固定在目标位置。
元素定位表现为在跨越特定阈值前为相对定位,之后为固定定位。
这个特定阈值指的是 top, right, bottom 或 left 之一,换言之,指定 top, right, bottom 或 left 四个阈值其中之一,才可使粘性定位生效。否则其行为与相对定位相同。
正是由于超出目标区域才有固定效果,sticky元素效果完全受限于父级元素,使用条件:
1.sticky元素的父元素的overflow只能设置为visible,否则会导致没有粘滞效果
2.sticky元素的父元素不能设置固定的高度,否则会导致没有粘滞效果
3.sticky满足条件变成fixed定位时,与标准fixed元素不一样,不会脱离文档流
4.sticky 定位的元素不能添加一个只包含自身的父元素,会导致没有粘滞效果
5.同一个父级元素中的sticky元素,如果定位值相等,则会重叠,如果属于不同父级元素中,则会挤掉之前的元素
而且兼容性也不是很好,在ie下全部不适用,既然使用sticky限制条件较多,那就要找其他办法了最近遇到一个需求中有个实现吸顶效果,即页面滚动到顶部,某元素固定到底部,离开顶部后回到原位置。
第一反应就是position: sticky;毕竟之前使用过,感觉效果很好,本以为一个sticky就可以大功告成,可现实啪啪打脸呐,一查才知sticky使用有诸多条件。先来看看position:sticky 是什么\
一. position:sticky
基于用户的滚动位置来定位。粘性定位的元素是依赖于用户的滚动,在 position:relative 与 position:fixed 定位之间切换。
它的行为就像 position:relative; 而当页面滚动超出目标区域时,它的表现就像 position:fixed; ,它会固定在目标位置。
元素定位表现为在跨越特定阈值前为相对定位,之后为固定定位。
这个特定阈值指的是 top, right, bottom 或 left 之一,换言之,指定 top, right, bottom 或 left 四个阈值其中之一,才可使粘性定位生效。否则其行为与相对定位相同。
正是由于超出目标区域才有固定效果,sticky元素效果完全受限于父级元素,使用条件:
1.sticky元素的父元素的overflow只能设置为visible,否则会导致没有粘滞效果
2.sticky元素的父元素不能设置固定的高度,否则会导致没有粘滞效果
3.sticky满足条件变成fixed定位时,与标准fixed元素不一样,不会脱离文档流
4.sticky 定位的元素不能添加一个只包含自身的父元素,会导致没有粘滞效果
5.同一个父级元素中的sticky元素,如果定位值相等,则会重叠,如果属于不同父级元素中,则会挤掉之前的元素
而且兼容性也不是很好,在ie下全部不适用,既然使用sticky限制条件较多,那就要找其他办法了
二.使用offsetTop
HTMLElement.offsetTop 为只读属性,它返回当前元素相对于其 offsetParent 元素的顶部内边距的距离。因此我们需要注意的是,在监听页面滚动的过程中,需要将定位父级元素的偏移量也计算在内,可以如下写法:
//获取当前元素的offsetTop
getOffsetTop(obj) {
let offsetTop = 0;
while (obj != window.document.body && obj != null) {
offsetTop += obj.offsetTop;
obj = obj.offsetParent;
}
return offsetTop;
}
通过添加监听事件滚动的事件:
window.addEventListener("scroll", handleScroll);
/**滚动事件 */
function handleScroll() {
//获取页面滚动条的高度
let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
let offsetTop = getOffsetTop(element);
return scrollTop > offsetTop;
}
三、使用getBoundingClientRect().top
还有一种更为直接的方式,可以实现吸顶效果,就是使用getBoundingClientRect().top来获取元素相对于视口(浏览器窗口)的位置,相对于offsetTop,该方法不用考虑到吸顶元素的父级元素和页面滚动条的高度,直接对该元素进行处理即可
/**滚动事件 */
function handleScroll() {
/**
* getBoundingClientRect().top 获取某元素距离浏览器顶部的高度,不包含滚动的距离
offsetTop 表示的是吸顶元素距离顶部的条件值(一般项目需求是0)
*/
let tabOffsetTop = document.getElementById('element').stickyBox.getBoundingClientRect().top;
return tabOffsetTop < offsetTop
}
以上就是实现需求得三个方式,也许还有更好得方法,待大家指教。