基于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 相关文章推荐
探索Emberjs制作一个简单的Todo应用
Nov 07 Javascript
javascript确认框的三种使用方法
Dec 17 Javascript
js阻止默认浏览器行为与冒泡行为的实现代码
May 15 Javascript
JQuery之proxy实现绑定代理方法
Aug 01 Javascript
微信+angularJS的SPA应用中用router进行页面跳转,jssdk校验失败问题解决
Sep 09 Javascript
JavaScript自定义分页样式
Jan 17 Javascript
vue项目中引入noVNC远程桌面的方法
Mar 05 Javascript
利用vue重构有赞商城的思路以及总结整理
Feb 21 Javascript
jquery将json转为数据字典的实例代码
Oct 11 jQuery
在JavaScript中实现链式调用的实现
Dec 24 Javascript
vue-quill-editor的使用及个性化定制操作
Aug 04 Javascript
javascript实现多边形碰撞检测
Oct 24 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数组函数序列之end() - 移动数组内部指针到最后一个元素,并返回该元素的值
2011/10/31 PHP
Yii2处理密码加密及验证的方法
2019/05/12 PHP
jquery入门——事件机制之事件中的冒泡现象示例解释
2020/09/12 Javascript
js如何设置在iframe框架中指定div不显示
2013/12/04 Javascript
JQuery对表单元素的基本操作使用总结
2014/07/18 Javascript
jquery append()方法与html()方法的区别及使用介绍
2014/08/01 Javascript
javascript判断变量是否有值的方法
2015/04/20 Javascript
JQuery实现超链接鼠标提示效果的方法
2015/06/10 Javascript
JavaScript 封装一个tab效果源码分享
2015/09/15 Javascript
JS禁用页面上所有控件的实现方法(附demo源码下载)
2015/12/17 Javascript
学习JavaScript设计模式之状态模式
2016/01/08 Javascript
Node.js中常规的文件操作总结
2016/10/13 Javascript
JS实现含有中文字符串的友好截取功能分析
2017/03/13 Javascript
微信小程序中顶部导航栏的实现代码
2017/03/30 Javascript
详解如何在Angular中快速定位DOM元素
2017/05/17 Javascript
Element-UI踩坑之Pagination组件的使用
2018/10/29 Javascript
微信小程序左滑删除功能开发案例详解
2018/11/12 Javascript
用node撸一个监测复联4开售短信提醒的实现代码
2019/04/10 Javascript
jQuery实现动态加载(按需加载)javascript文件的方法分析
2019/05/31 jQuery
nodejs对项目下所有空文件夹创建gitkeep的方法
2019/08/02 NodeJs
python 写的一个爬虫程序源码
2016/02/28 Python
Python企业编码生成系统总体系统设计概述
2019/07/26 Python
python 哈希表实现简单python字典代码实例
2019/09/27 Python
3种适用于Python的疯狂秘密武器及原因解析
2020/04/29 Python
利用python汇总统计多张Excel
2020/09/22 Python
Pycharm编辑器功能之代码折叠效果的实现代码
2020/10/15 Python
解释一下钝化(Swap out)
2016/12/26 面试题
《花瓣飘香》教学反思
2014/04/15 职场文书
设备售后服务承诺书
2014/05/30 职场文书
驾驶员安全责任书范本
2014/07/24 职场文书
民政局副局长民主生活会个人对照检查材料
2014/09/19 职场文书
大学生迟到检讨书500字
2014/10/17 职场文书
2014年宣传工作总结
2014/11/18 职场文书
2019年工作总结范文
2019/05/21 职场文书
Python turtle实现贪吃蛇游戏
2021/06/18 Python
Java中使用Filter过滤器的方法
2021/06/28 Java/Android