页面中元素的吸顶

2022-11-02 14:31:22 浏览数 (2)


携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第11天,点击查看活动详情 >>

[前言]

现在由于医嘱开立界面需要对新开的输入框进行首行或者尾行的行固定效果,使用的实现方案只能在谷歌浏览器90.0版本以后才支持。故需要框架组提供另一套兼容低版本谷歌浏览器的实现方案。

[需求]

  1. 滚动页面到顶部,实现某元素固定到顶部效果
  2. 点击某个按钮,页面滚动到相应的位置
  3. 滚动页面,当到达某个位置时,高亮对应的相关按钮

[元素吸顶实现方式]

关于元素吸顶效果,通过查阅相关资料和相关测试,有三种方式(还有一种是jquery的方法,这里就不介绍了)

[一、使用position:sticky]

[1. 什么是position:sticky?]

粘性定位元素相当于position:relative和position:sticky的结合体,受限于父级元素,在不同的条件下呈现出不同的页面效果

[2. 如何使用sticky?]

sticky元素效果完全受限于父级元素,使用条件:

  • sticky元素的父元素的overflow只能设置为visible,否则会导致没有粘滞效果
  • sticky元素的父元素不能设置固定的高度,否则会导致没有粘滞效果
  • sticky满足条件变成fixed定位时,与标准fixed元素不一样,不会脱离文档流
  • sticky 定位的元素不能添加一个只包含自身的父元素,会导致没有粘滞效果
  • 同一个父级元素中的sticky元素,如果定位值相等,则会重叠,如果属于不同父级元素中,则会挤掉之前的元素,形成依次占位的效果 具体实现效果如下:
代码语言:javascript复制
.sticky-box{  
 position: sticky;  
 position: -webkit-sticky;
 top: 60px; //可通过js动态设置
}
[3.兼容性]

通过查看can i use 可以看到相关的兼容性: 只能在谷歌浏览器90.0版本以后才支持。

可以看出这个属性的兼容性不是那么好,如果项目需要兼容到ie11等的话,就不是那么适用了

[二、使用offsetTop]

HTMLElement.offsetTop 为只读属性,它返回当前元素相对于其 offsetParent 元素的顶部内边距的距离。因此我们需要注意的是,在监听页面滚动的过程中,需要将定位父级元素的偏移量也计算在内,可以如下写法:

代码语言:javascript复制
    //获取当前元素的offsetTop
    getOffsetTop(obj) {
      let offsetTop = 0;
      while (obj != window.document.body && obj != null) {
        offsetTop  = obj.offsetTop;
        obj = obj.offsetParent;
      }
      return offsetTop;
    }

通过在vue的mounted生命周期函数中添加监听事件滚动的事件:

代码语言:javascript复制
 mounted() {
    /**通过给变成固定定位的元素添加一个同等高度的父元素,防止该元素变成固定定位时,脱离文档流导致的页面抖动 */
    this.tabsHeight = this.$refs.elTabs.offsetHeight;
    window.addEventListener("scroll", this.handleScroll);
  },
  destroyed() {
    //离开该页面需要移除这个监听的事件
    window.removeEventListener("scroll", this.handleScroll);
  },
   methods: {
    /**滚动事件 */
    handleScroll() {
        //获取页面滚动条的高度
        let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
        let offsetTop = this.getOffsetTop(this.$refs.elTabs);
        this.isFixed = scrollTop > offsetTop;
    }
  }

[三、使用getBoundingClientRect().top]

还有一种更为直接的方式,可以实现吸顶效果,就是使用getBoundingClientRect().top来获取元素相对于视口(浏览器窗口)的位置,相对于offsetTop,该方法不用考虑到吸顶元素的父级元素和页面滚动条的高度,直接对该元素进行处理即可,实现如下:

代码语言:javascript复制
     /**滚动事件 */
    handleScroll() {
      /**
       * getBoundingClientRect().top 获取某元素距离浏览器顶部的高度,不包含滚动的距离
       this.offsetTop 表示的是吸顶元素距离顶部的条件值(一般项目需求是0)
       */
      let tabOffsetTop = this.$refs.stickyBox.getBoundingClientRect().top;
      this.isFixed = tabOffsetTop < this.offsetTop
    }

0 人点赞