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


Posted in Javascript onJanuary 17, 2018

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

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

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

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

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

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

:scrollTop(滚动之根本)

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

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

一、组件html结构:

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

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

注意看注释::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)
  },

这里写的有点??铝耍?柚?etTimeout延迟是为了能够获取到元素(谁有好办法快推荐给我),为了在滚动中能够对应列表显示锚点当前状态,存了一个数据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。但是一时也没有更好的办法来实现。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
浅析jQuery对select操作小结(遍历option,操作option)
Jul 04 Javascript
javascript date格式化示例
Sep 25 Javascript
JavaScript中的toLocaleDateString()方法使用简介
Jun 12 Javascript
JS基于HTML5的canvas标签实现炫目的色相球动画效果实例
Aug 24 Javascript
详解react内联样式使用webpack将px转rem
Sep 13 Javascript
JavaScript 高性能数组去重的方法
Sep 20 Javascript
jqGrid表格底部汇总、合计行footerrow处理
Aug 21 Javascript
在layui.use 中自定义 function 的正确方法
Sep 16 Javascript
小程序实现投票进度条
Nov 20 Javascript
利用原生JS实现欢乐水果机小游戏
Apr 23 Javascript
详解用js代码触发dom事件的实现方案
Jun 10 Javascript
在vue中对数组值变化的监听与重新响应渲染操作
Jul 17 Javascript
详解微信小程序审核不通过的解决方法
Jan 17 #Javascript
swiper动态改变滑动内容的实现方法
Jan 17 #Javascript
基于 Vue.js 2.0 酷炫自适应背景视频登录页面实现方式
Jan 17 #Javascript
使用Vue开发一个实时性时间转换指令
Jan 17 #Javascript
angularjs 页面自适应高度的方法
Jan 17 #Javascript
VueJs监听window.resize方法示例
Jan 17 #Javascript
详解AngularJS之$window窗口对象
Jan 17 #Javascript
You might like
php分页代码学习示例分享
2014/02/20 PHP
PHP匿名函数(闭包函数)详解
2019/03/22 PHP
从javascript语言本身谈项目实战
2006/12/27 Javascript
jQuery 对象中的类数组操作
2009/04/27 Javascript
js控制的遮罩层实例介绍
2013/05/29 Javascript
JavaScript实现的购物车效果可以运用在好多地方
2014/05/09 Javascript
JavaScript中eval()函数用法详解
2015/12/14 Javascript
基于javascript实现九九乘法表
2016/03/27 Javascript
全面了解javascript中的错误处理机制
2016/07/18 Javascript
JS 实现计算器详解及实例代码(一)
2017/01/08 Javascript
js实现可以点击收缩或张开的悬浮窗
2017/09/18 Javascript
vue2.0 常用的 UI 库实例讲解
2017/12/12 Javascript
JavaScript创建防篡改对象的方法分析
2018/12/30 Javascript
React路由鉴权的实现方法
2019/09/05 Javascript
[00:06]Yes,it worked!小卡尔成功穿越时空加入战场!
2019/07/20 DOTA
决策树的python实现方法
2014/11/18 Python
简单了解python PEP的一些知识
2019/07/13 Python
Pytorch 抽取vgg各层并进行定制化处理的方法
2019/08/20 Python
如何使用python进行pdf文件分割
2019/11/11 Python
Python collections模块的使用方法
2020/10/09 Python
使用css3做0.5px的细线的示例代码
2018/01/18 HTML / CSS
美国咖啡批发网站:Coffee.org
2017/06/29 全球购物
TripAdvisor台湾:全球最大旅游网站
2018/08/26 全球购物
Shopee越南:东南亚与台湾电商平台
2019/02/03 全球购物
Juice Beauty官网:有机美容产品,护肤与化妆品
2020/06/13 全球购物
大堂副理的岗位职责范文
2014/02/17 职场文书
美术指导助理求职信
2014/04/20 职场文书
文明演讲稿范文
2014/05/12 职场文书
运动会广播稿200字
2014/10/18 职场文书
乡镇民主生活会发言材料
2014/10/20 职场文书
优秀教师个人材料
2014/12/15 职场文书
三峡人家导游词
2015/01/31 职场文书
淮海战役观后感
2015/06/11 职场文书
python实现图片九宫格分割的示例
2021/04/25 Python
MySQL 语句执行顺序举例解析
2022/06/05 MySQL
MySQL 原理与优化之原数据锁的应用
2022/08/14 MySQL