基于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 设置值一直没有作用。


原文链接

扫描二维码关注公众号,回复: 2258390 查看本文章

猜你喜欢

转载自blog.csdn.net/qigentan/article/details/81114703