当前位置: 移动技术网 > IT编程>脚本编程>vue.js > 基于vue监听滚动事件实现锚点链接平滑滚动的方法

基于vue监听滚动事件实现锚点链接平滑滚动的方法

2018年01月26日  | 移动技术网IT编程  | 我要评论

等高线图,闪电侠第二季第八集,小77最新地址

基于vue监听滚动事件,实现锚点链接平滑滚动

近日在做一个vue项目的餐饮模块,小编需要实现一个菜单列表显示的功能(如图所示:左边为菜单类别,右边显示相对应的菜品)

小编将此分为三个功能模块来实现(本来一张动画就清晰明了,小编太笨,只得口述一下):

1.左边点击类别,右边显示相应类别的菜品列表(平滑滚动)
2.滚动右边的滚动条,左边对应的显示当前样式
3.若从别的页面点击菜品进来该页面,则该菜品为指定效果

小编也是vue的初学者,在阅读了大量的文章后,其中借鉴 该文章,收到了很多启发后,结合我们的功能加以完善。小编的和借鉴的文章侧重点不同,建议大家在看之前可以先看一下上面的,以便于梳理的更清楚。

:scrolltop(滚动之根本)

在初写项目的尝试过程中,小编一直改变的是document.body.scrolltop的值来实现滚动,但是后来逐渐发现很邪门,有时给其赋值并没有作用,而且过程也很麻烦,又查阅了一些资料也没有解决办法,所以不得已放弃。

之后无意中看到:scrolltop, 便尝试开始使用vue中的属性直接进行绑定滚动的变量值,功能实现反而简单了。下面详细讲述:

一、组件html结构:

结构布局很简单,在此多说是想给大家讲述清楚一点儿右边菜品的结构,方便绑定:scrolltop属性,小编就踩了这个坑...

注意看注释::scrolltop 的位置改变菜品列表的scrolltop值,来实现相应的滚动

二、实现锚链接平滑滚动

该功能是参考之前博主的文章的,方法基本没改什么,简单易懂,直接放代码

jump(index){
    const cateitem = document.queryselectorall('.cate-item');
    let total = cateitem[index].offsettop;
    let distance = this.container.scrolltop // 获取到顶部的距离(this.container便是.cate-list,为了方便存起来了)
    let step = total / 50;
    this.isactive = index; // 菜单列表显示当前样式
    const _this = this;
    if (total > distance) {
     smoothdown()
    } else {
     let newtotal = distance - total
     step = newtotal / 50
     smoothup()
    }
    function smoothdown () {
     if (distance < total) {
     distance += step
     _this.scrolltop = distance;
     settimeout(smoothdown, 10);
     } else {
     _this.scrolltop = total
     }
    }
    function smoothup () {
     if (distance > total) {
     distance -= step
     _this.scrolltop = distance
     settimeout(smoothup, 10)
     } else {
     _this.scrolltop = total
     }
    } 
    }

三、监听滚动事件,修改锚点状态

在vue中钩子函数监听菜品列表(this.container)的滚动事件,

 mounted(){
   // 监听scroll事件
   const _this = this;
   settimeout(function(){
    _this.currentstick(); 
    const rightitem = document.queryselectorall('.cate-item');
    const catelist = document.queryselectorall('.cate-list')[0];
    var length = rightitem.length;
    var height = rightitem[length-1].offsetheight;
    var scrollheight = document.queryselectorall('.cate-menu-wrapper')[0].offsetheight;
    // 设置最后一个类别菜品列表的高度(小于适配器高度的话与适配器等高),不然点击锚点不能够置顶
    if(height < scrollheight){
     rightitem[length-1].style.height = scrollheight+'px';
    } 
    var arr =[];
    rightitem.foreach(function(v, i){
     arr.push({top: v.offsettop, height: v.offsetheight, index: i});
    })
    _this.itemval = arr; 
    const catelist = document.queryselectorall('.cate-list')[0];
    catelist.addeventlistener('scroll', _this.onscroll);
    _this.container = catelist;
   }, 500)
  },

这里写的有点啰嗦了,设置settimeout延迟是为了能够获取到元素(谁有好办法快推荐给我),为了在滚动中能够对应列表显示锚点当前状态,存了一个数据itemall,存了该菜品类别区域的scrolltop,索引,高度。(啰嗦,太啰嗦了)

methods: {
 onscroll () {
    var _this = this;
    _this.itemval.foreach(function(obj, i){
     _this.scrolltop = _this.container.scrolltop;
     if(_this.scrolltop >= obj.top && _this.scrolltop < (obj.top + obj.height-10)){
      // scrolltop的移动位置要在类别的菜品列表中才显示对应锚点的当前状态
      _this.isactive = obj.index;
     }
    })
   },
}

三、点击菜品进入页面,该菜品置顶的联动效果(该功能其实有隐藏性的bug,我们项目已取消该功能)

currentstick(){
     const {dishid} = this.$route.query;
     const catecontent = document.queryselectorall('.cate-content');
     const _this = this;
     catecontent.foreach(function(v, i){
      if(v.id == dishid){
       _this.scrolltop = v.offsettop; 
      }
     })
   },

该功能用:scrolltop绑定的话便简单了许多,之前用document.body.scrolltop 设置值一直没有作用。

好了,基本上所有的代码都帖出来了,说的应该也详细吧(我尽力了),该方法感觉其实还是在操作dom元素和js,枉用vue。但是一时也没有更好的办法来实现。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网