美文网首页
vue 盒子滚动吸顶效果的实现

vue 盒子滚动吸顶效果的实现

作者: 风雨兼程620 | 来源:发表于2019-09-30 17:21 被阅读0次

    在优化项目的时候, 产品提出需求需要在页面滚动到当前元素下面的时候, 此元素自动固定到页面最顶部, 就是类似于百度的吸顶效果,如图

    百度搜索打开进入时 吸顶效果

    话不多算,直接上干货:

       你在网上找到的一般是这样的实现代码

    通过监听body向上卷起的距离动态的给目标元素添加固定定位的css属性

    但是:

    这样的代码能实现需求吗?   并不能, 在移动端可以,但是在PC端不行的

    我就试着写了一个原生的demo,发现原生的是可以实现需求的,因为我们是vue项目,所以这里就不重点体现;


    解决方案(免费)

    最终通过很久的研究,实现了需求:

    使用 obj.getBoundingClientRect().top 

    定义:这个 API 可以告诉你页面中某个元素相对浏览器视窗上下左右的距离。

    使用:tab 吸顶可以使用 obj.getBoundingClientRect().top 代替 scrollTop - offsetTop,代码如下:

    //css

    .isFixed{

            position: fixed;

            top: 60px;//自己根据需求设定

            z-index: 999;

            width: 100%;

        }

    // html

    <div class="container" ref="fixedHeaderRoot" id="fixedHeaderRoot" >

        <div class="title-box" :class="headerFixed== true ? 'isFixed' :''">

            // some code

        </div>

    </div>

    // vue

    export default {

        data(){

          return{

            headerFixed: false

          }

        },

        created() {//// 事件监听滚动条

          this.headerFixed= false;

          window.addEventListener('scroll', this.handleScroll,true)//建议第三个参数为true,我原来没有设置导致没有深度监听

        },

        methods: {

          //主要处理函数, 判断目标元素吸顶的时机

          handleScroll () {

            let offsetTop = this.$refs.fixedHeaderRoot.getBoundingClientRect().top;

            this.headerFixed = offsetTop<0?true:false

            // some code

          }

        },

      }

    实现方法也是通过动态给目标元素增加固定定位的属性, 相信仔细研究,一眼你就能明白

    但是.你以为这样就结束了,你会发现

    有时好的,有时报错

    这是为什么呢,可能滚动的太频繁,页面还没有重新加载到  this.$refs;所以,我的解决办法想当的简单:

    //css

    .isFixed{

            position: fixed;

            top: 60px;//自己根据需求设定

            z-index: 999;

            width: 100%;

        }

    // html

    <div class="container" ref="fixedHeaderRoot" id="fixedHeaderRoot"  >   

        <div class="title-box" :class="headerFixed== true ? 'isFixed' :''">       

        // some code   

        </div>

    </div>

    // vue

    export default {

        data(){

          return{

            headerFixed: false

          }

        },

        created() {//// 事件监听滚动条

          this.headerFixed= false;

          window.addEventListener('scroll', this.handleScroll,true)//建议第三个参数为true,我原来没有设置导致没有深度监听

        },

        methods: {

          //主要处理函数, 判断目标元素吸顶的时机

          handleScroll () {

            let offsetTop = this.$refs.fixedHeaderRoot.getBoundingClientRect().top;

            let offsetTop = this.$el.querySelector('#fixedHeaderRoot').getBoundingClientRect().top;

            this.headerFixed = offsetTop<0?true:false

          }

        },

            destroyed() {//组件销毁时解除监听

                window.removeEventListener("scroll", this.handleScroll);

            },

    }

    在使用中发现如下报错:

    api为null

    经过排查发现是路由改变组价销毁,但其实页面并没有关闭, 此时我们已经解除了滚动监听, 所以报Cannot read property 'getBoundingClientRect' of null

    所以, 取消生命周期(销毁后的解除滚动监听)

    //组件销毁时解除监听 

    destroyed() {               window.removeEventListener("scroll", this.handleScroll);        },

    相关文章

      网友评论

          本文标题:vue 盒子滚动吸顶效果的实现

          本文链接:https://www.haomeiwen.com/subject/yedluctx.html