Vue中监听滚动事件

4,441 阅读1分钟

After the night I burned all memory, 
my dream becomes transparent, 
as I trashed all yesterdays, 
my step becomes lighter.

有一个夜晚我烧毁了所有的记忆,
从此我的梦就透明了;
有一个早晨我扔掉了所有的昨天,
从此我的脚步就轻盈了。

             ——《烧毁记忆》泰戈尔

说明

最近在一个Vue项目中,想要实现侧边栏距离浏览器顶部一定距离后固定的效果,需要监听scroll事件,刚开始的想法是给顶级div添加scroll事件,如下所示,但是不生效。

<div @scroll="setNavPosition"></div>

不生效的原因是,这个div是最顶级的元素,scroll只有在子级产生滚动,在父级添加监听事件才会起作用,而这里监听的已经是最父级的元素了,所以添加scroll事件不生效。

解决方法

解决方式是,在mounted生命周期内,给window元素添加scroll事件,并在destroyed生命周期内销毁该事件,具体代码如下:

<div id="item-nav">
    导航
    ……
</div>
#item-nav {
  height: 386px;
  /* 需要设置该侧边栏为fixed定位 */
  position: fixed;
  top: 85px;
  /* 由于我设置了元素为flex定位,当该元素设为fixed后,元素会从文档流脱离,会影响布局,
  需要设置一下侧边栏的位置才可以 */
  left: calc(50% + 500px);
  width: 120px;
}
methods: {
 setNavPosition() {
    var nav = document.getElementById("item-nav");
    var scroll_height =
    document.body.scrollTop || document.documentElement.scrollTop || window.pageYOffset;
    if (scroll_height > 65) {
      // 浏览器滚动高度超出一定范围后,侧边栏固定
      nav.style.top = "20px";
    } else {
      // 未超出范围,跟随浏览器一起滚动
      nav.style.top = 85 - scroll_height + "px";
    }
  }
}

mounted() {
   window.addEventListener("scroll", this.setNavPosition);
},
 
destroyed() {
   //离开该页面需要移除这个监听的事件
   window.removeEventListener("scroll", this.setNavPosition);
}