基于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 相关文章推荐
Javascript匿名函数的一种应用 代码封装
Jun 27 Javascript
jquery实现固定顶部导航效果(仿蘑菇街)
Mar 21 Javascript
js获得地址栏?问号后参数的方法
Aug 08 Javascript
node.js中的fs.unlink方法使用说明
Dec 15 Javascript
JavaScript中的变量作用域介绍
Dec 31 Javascript
jquery实现鼠标经过显示下划线的渐变下拉菜单效果代码
Aug 24 Javascript
jQuery的ajax下载blob文件
Jul 21 Javascript
JavaScript正则表达式的贪婪匹配和非贪婪匹配
Sep 05 Javascript
layui select动态添加option的实例
Mar 07 Javascript
快速解决brew安装特定版本flow的问题
May 17 Javascript
JavaScript中的this原理及6种常见使用场景详解
Feb 14 Javascript
如何实现echarts markline标签名显示自己想要的
Jul 20 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 5.3.x 的strtotime() 时区设定 警告信息修复
2013/08/05 PHP
php采集内容中带有图片地址的远程图片并保存的方法
2015/01/03 PHP
利用PHP命令行模式采集股票趋势信息
2016/08/09 PHP
实例讲解通过​PHP创建数据库
2019/01/20 PHP
tp5框架前台无限极导航菜单类实现方法分析
2020/03/29 PHP
JavaScript的parseInt 取整使用
2011/05/09 Javascript
Jquery 复选框取值兼容FF和IE8(测试有效)
2013/10/29 Javascript
让alert不出现弹窗的两种方法
2014/05/18 Javascript
node.js中的fs.readdirSync方法使用说明
2014/12/17 Javascript
DOM 高级编程
2015/05/06 Javascript
javascript创建含数字字母的随机字符串方法总结
2016/08/01 Javascript
vue 打包后的文件部署到express服务器上的方法
2017/08/09 Javascript
基于JavaScript实现淘宝商品广告效果
2017/08/10 Javascript
JavaScript登录验证基础教程
2017/11/01 Javascript
JS实现遍历不规则多维数组的方法
2018/03/21 Javascript
解决vue2.0路由跳转未匹配相应用路由避免出现空白页面的问题
2018/08/24 Javascript
jQuery实现的淡入淡出图片轮播效果示例
2018/08/29 jQuery
nodemon实现Typescript项目热更新的示例代码
2019/11/19 Javascript
2019年度web前端面试题总结(主要为Vue面试题)
2020/01/12 Javascript
[23:21]Ti4 冒泡赛第二轮DK vs C9 2
2014/07/14 DOTA
[01:08:17]2018DOTA2亚洲邀请赛3月29日 小组赛B组 EG VS VGJ.T
2018/03/30 DOTA
pyqt4教程之实现windows窗口小示例分享
2014/03/07 Python
在Python的Django框架中为代码添加注释的方法
2015/07/16 Python
在Python中移动目录结构的方法
2016/01/31 Python
python列表的增删改查实例代码
2018/01/30 Python
Python3 无重复字符的最长子串的实现
2019/10/08 Python
使用Python和OpenCV检测图像中的物体并将物体裁剪下来
2019/10/30 Python
PyCharm取消波浪线、下划线和中划线的实现
2020/03/03 Python
阿玛尼化妆品美国官网:Giorgio Armani Beauty
2017/02/02 全球购物
美国折扣宠物药房:Total Pet Supply
2018/05/27 全球购物
bonprix匈牙利:女士、男士和儿童服装
2019/07/19 全球购物
高级编程求职信模板
2014/02/16 职场文书
会计助理岗位职责
2014/02/17 职场文书
诚信贷款承诺书
2014/05/30 职场文书
2014年路政工作总结
2014/12/10 职场文书
2016年“世界气象日”广播稿
2015/12/17 职场文书