吸顶是一种常见的设计样式,即组件一开始随着节目滚动,但触碰到某个边界后吸附在其上固定下来。比如百度首页的搜索框的吸顶效果。
滚动后的效果图如下所示:
那么对于这种很普遍的吸顶,有哪些实现方式呢?
position: sticky
MDN的CSS文档关于postion的可用参数中,有一个sticky,其含义为:
粘性定位元素 ( stickily positioned element ) 是计算后位置属性为
sticky的元素元素根据正常文档流进行定位,然后相对它的最近滚动祖先(nearest scrolling ancestor) 和 containing block (最近块级祖先 nearest block-level ancestor),包括table-related元素,基于
top,right,bottom, 和left的值进行偏移。偏移值不会影响任何其他元素的位置。
这种实现方式简便快捷,其具体实现要求可概括为:
- 父元素可滚动 2、需指定top、bottom、left、right4个值之一
另外需要注意的一点是,该特性是css新增特性,可能存在浏览器的支持问题,其具体支持情况如下图所示:
并且实现时,保险起见一般添加上:position: -webkit-sticky
样例代码
.sticky {
position: -webkit-sticky;
position: sticky;
top: 0;
}
动态样式
在实际生产中,没有使用sticky主要是考虑其浏览器的支持不全面。因此采用了动态样式。
思路很简单:给父元素添加scroll监听函数,侦听函数内部判断当前吸顶组件距离边界的距离,若其距离小于等于0,则修改其样式为:position:fixed;...,以VUE框架为例(只会VUE~哭),具体实现代码:
<template>
...
<div ref="tabRow" :class={'fixed': fixed}></div>
...
</template>
<script>
...
data() {
return {
fixed: false
}
},
mounted: {
this.$nextTrick(() => {
// tabRow为组件的ref值
// 获取组件初始距离页面顶部的距离
this.offsetTop = this.$refs.tabRow.getBoundingClientRect().top;
/**添加侦听函数*/
window.addEventListener('scroll' , this.handleScroll);
})
},
methods: {
handleScroll() {
// 屏幕当前的滚动距离
let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
if (scrollTop >= this.offsetTop) {
this.fixed = true
} else {
this.fixed = false
}
}
},
destroyed() {
window.removeEventListener("scroll", this.handleScroll);
}
...
</script>
<style>
...
.fixed {
position: fixed;
left: 0;
top: 0;
}
...
</style>