vue左右侧联动滚动的实现代码


Posted in Javascript onJune 06, 2018

本文介绍了vue左右侧联动滚动的实现代码,分享给大家,具体如下:

实现功能:

  1. 点击左侧,右侧滚动到相应位置,
  2. 滚动右侧, 左侧滚动到相应位置

vue左右侧联动滚动的实现代码

布局结构:

vue左右侧联动滚动的实现代码

开源滚动库:

better-scroll.js

技术要点:

1.<scroll>是对紧邻的元素生效

如:

<scroll class='foods-wrapper'>
  <ul class=content>
   <li></li>
  </ul>
 </scroll>

初始化在<ul>元素上

2.foods-wrapper的高度小于content高度时才会发生滚动

3.点击左侧菜单列表时,只需要计算右侧对应的偏移距离 或是 计算对应的移动到的元素即可

方法一: 计算移动距离, 用scrollTo()方法

for (let i = 0; i < index; i++) {
  height += this.$refs.item[i].offsetHeight
 }
 this.$refs.foodsWrapper.scrollTo(0, -height)

方法二: 计算移动到的元素,用scrollToElement()方法

let foodsEle = this.$refs.foodsUl.getElementsByClassName('item')[index]
 this.$refs.foodsWrapper.scrollToElement(foodsEle, 400)

4.滚动右侧列表时,会稍复杂一些.

4.1. 因为需要知道滚动的元素在哪个item列表区间, 因此需要计算右侧五组item距离顶部的距离

_heightArr () {
 let h = 0
 let list = this.$refs.item
 list.forEach((item, i) => {
  h += list[i].clientHeight
  this.itemHeight.push(h)
 })
  console.log(this.itemHeight) //[0, 481, 850, 2227, 2820, 3189]
}

4.2 时时监听滚动距离

需要在<scroll>中加以下参数

<scroll class='foods-wrapper' :listenScroll=listenScroll :probeType = 'probeType' @scroll=scroll>

其中 listenScroll probeType参数 在created中定义:

created () {
  this.listenScroll = true
  this.probeType = 3
 }

而@scroll=scroll是在scroll.vue中代理过来的方法:

//scroll.vue
 if (this.listenScroll) {
  let me = this
  this.scroll.on('scroll', (position) => {
   me.$emit('scroll', position) //参数position: position:{x:-10, y:24}
  })
 }

posiiton.y就是需要实时监听的参数,即:

scroll (position) {
 this.scrolly = position.y
}

其中 scrolly 需要在data中提前定义:

data () {
  return {
   scrolly: -1
  }
 }

然后在watch中监听scrolly变化即可:

watch: {
  scrolly (newy) {
   if (newy >= 0) this.currentIndex = 0
   let itemHeight = this.itemHeight
   for (let i = 0; i < itemHeight.length - 1; i++) {
    let h1 = itemHeight[i]
    let h2 = itemHeight[i + 1]
    if (-newy >= h1 && -newy < h2) {
     this.currentIndex = i
     return
    }
   }
  }
 }

代码部分:

//左侧结构
 <scroll class='menu-wrapper'>
  <ul>
   <li 
    v-for='(item,index) in foodsList' 
    :key=index 
     class=item 
    :class="{active:currentIndex === index}" 
    @click=selectMenu(index)
   >
    <span>{{item.name}}</span>
   </li>
  </ul>
 </scroll>


//右侧结构
 <scroll class='foods-wrapper' ref=foodsWrapper :listenScroll=listenScroll :probeType = 'probeType' @scroll=scroll>
  <ul ref=foodsUl> 
   <li v-for='(item,index) in foodsList' :key=index class=item ref=item :data-index=index>
    <div class=title><span class='title-name'>{{item.name}}</span><span>{{item.description}}</span></div>
    <ul>
     <li v-for='(food,i) in item.foods' :key=i class=food>
     //.........
     //略去右侧详情代码
     </li>
    </ul>
   </li>
  </ul>
 </scroll>

//js部分
<script>
import Scroll from "base/scroll"
const H = 112
export default {
 data () {
  return {
   currentIndex: 0,
   offset: 0,
   scrolly: -1
  }
 },
 created () {
  this.listenScroll = true
  this.probeType = 3
  this.itemHeight = [0]
 },
 mounted () {
  this.$nextTick(() => {
   this._heightArr()
  }, 20);
 },
 methods: {
  selectMenu (index) {
   let height = 0
   this.currentIndex = index

   for (let i = 0; i < index; i++) {
    height += this.$refs.item[i].offsetHeight
   }

   let foodsEle = this.$refs.foodsUl.getElementsByClassName('item')[index]
   this.$refs.foodsWrapper.scrollToElement(foodsEle, 400)
   // this.$refs.foodsWrapper.scrollTo(0, -height)
   this.offset = height
  },
  scroll (position) {
   this.scrolly = position.y
  },
  _heightArr () {
   let h = 0
   let list = this.$refs.item
   list.forEach((item, i) => {
    h += list[i].clientHeight
    this.itemHeight.push(h)
   })
  }
 },
 watch: {
  scrolly (newy) {
   if (newy >= 0) this.currentIndex = 0
   let itemHeight = this.itemHeight
   for (let i = 0; i < itemHeight.length - 1; i++) {
    let h1 = itemHeight[i]
    let h2 = itemHeight[i + 1]
    if (-newy >= h1 && -newy < h2) {
     this.currentIndex = i
     return
    }
   }
  }

 },
 components: {
  Scroll
 }


}
</script>
//scroll.vue
<template>
 <div ref=wrapper>
  <slot></slot> 
 </div>
</template>

<script>
import BScroll from 'better-scroll'
export default {
 props: {
  probeType: {
   type: Number,
   default: 1//* 1 滚动的时候会派发scroll事件,会截流。 * 2 滚动的时候实时派发scroll事件,不会截流。 * 3 除了实时派发scroll事件,在swipe的情况下仍然能实时派发scroll事件
  },
  click: {
   type: Boolean,
   default: true
  },
  scrollX: {
   type: Boolean,
   default: false
  },
  data: {
   type: Array,
   default: null
  },
  listenScroll: {
   type: Boolean,
   default: false
  },

 },
 mounted () {
  this.$nextTick(() => {
   this.initScroll()
  }, 20)
 },
 methods: {
  initScroll () {
   if (!this.$refs.wrapper) return
   this.scroll = new BScroll(this.$refs.wrapper, {
    probeType: this.probeType,
    click: this.click,
    scrollX: this.scrollX
   })

   if (this.listenScroll) {
    let me = this
    this.scroll.on('scroll', (position) => {
     me.$emit('scroll', position)

    })
   }
  },
  enable () {
   this.scroll && this.scroll.enable()
  },
  disable () {
   this.scroll && this.scroll.disable()
  },
  refresh () {
   this.scroll && this.scroll.refresh()
  },
  scrollTo () {
   this.scroll && this.scroll.scrollTo.apply(this.scroll, arguments)
  },

  scrollToElement () {
   this.scroll && this.scroll.scrollToElement.apply(this.scroll, arguments)
  }

 },
 watch: {
  data () {
   setTimeout(() => {
    this.scroll.refresh()
   }, 20)
  }
 }

}
</script>

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

Javascript 相关文章推荐
基于jquery的表格排序
Sep 11 Javascript
javascript实现信息的显示和隐藏如注册页面
Dec 03 Javascript
JS根据变量保存方法名并执行方法示例
Apr 04 Javascript
wap浏览自动跳转到wap页面的js代码
May 17 Javascript
JavaScript中var关键字的使用详解
Aug 14 Javascript
深入剖析JavaScript编程中的对象概念
Oct 21 Javascript
封装好的javascript前端分页插件pagination
Jan 04 Javascript
Vue.js每天必学之方法与事件处理器
Sep 06 Javascript
将json转换成struts参数的方法
Nov 08 Javascript
Node.js简单入门前传
Aug 21 Javascript
微信小程序学习笔记之表单提交与PHP后台数据交互处理图文详解
Mar 28 Javascript
JS实现贪吃蛇游戏
Nov 15 Javascript
Express本地测试HTTPS的示例代码
Jun 06 #Javascript
微信小程序仿美团城市选择
Jun 06 #Javascript
jQuery实现百度图片移入移出内容提示框上下左右移动的效果
Jun 05 #jQuery
详解封装基础的angular4的request请求方法
Jun 05 #Javascript
React.js绑定this的5种方法(小结)
Jun 05 #Javascript
微信小程序实现城市列表选择
Jun 05 #Javascript
vue.js将时间戳转化为日期格式的实现代码
Jun 05 #Javascript
You might like
PHP操作数组相关函数
2011/02/03 PHP
PHP教程之PHP中shell脚本的使用方法分享
2012/02/23 PHP
javascript css float属性的特殊写法
2008/11/13 Javascript
firefox事件处理之自动查找event的函数(用于onclick=foo())
2010/08/05 Javascript
jquery绑定原理 简单解析与实现代码分享
2011/09/06 Javascript
js 阻止子元素响应父元素的onmouseout事件具体实现
2013/12/23 Javascript
JavaScript中用sort()方法对数组元素进行排序的操作
2015/06/09 Javascript
html5+javascript实现简单上传的注意细节
2016/04/18 Javascript
JS基于HTML5的canvas标签实现炫目的色相球动画效果实例
2016/08/24 Javascript
Javascript 动态改变imput type属性
2016/11/01 Javascript
livereload工具实现前端可视化开发【推荐】
2016/12/23 Javascript
基于JavaScript中字符串的match与replace方法(详解)
2017/12/04 Javascript
Angular路由ui-router配置详解
2018/08/01 Javascript
详解基于Vue2.0实现的移动端弹窗(Alert, Confirm, Toast)组件
2018/08/02 Javascript
解决JavaScript中0.1+0.2不等于0.3问题
2018/10/23 Javascript
JS中的函数与对象的创建方式
2019/05/12 Javascript
nodejs一个简单的文件服务器的创建方法
2019/09/13 NodeJs
使用Vue实现简单计算器
2020/02/25 Javascript
nodejs中使用worker_threads来创建新的线程的方法
2021/01/22 NodeJs
[01:31:02]TNC vs VG 2019国际邀请赛淘汰赛 胜者组赛BO3 第一场
2019/08/22 DOTA
Python 修改列表中的元素方法
2018/06/26 Python
python bmp转换为jpg 并删除原图的方法
2018/10/25 Python
python绘制无向图度分布曲线示例
2019/11/22 Python
基于python 取余问题(%)详解
2020/06/03 Python
vscode+PyQt5安装详解步骤
2020/08/12 Python
Python全局变量与global关键字常见错误解决方案
2020/10/05 Python
如何使用Pytorch搭建模型
2020/10/26 Python
用html5的canvas和JavaScript创建一个绘图程序的简单实例
2016/07/06 HTML / CSS
广州某公司软件工程师面试题
2014/12/22 面试题
产品质量承诺书范文
2014/03/27 职场文书
护理目标管理责任书
2014/07/25 职场文书
自动化专业大学生职业生涯规划范文:爱拚才会赢
2014/09/12 职场文书
2014年客服工作总结范文
2014/11/13 职场文书
汽车销售员岗位职责
2015/04/11 职场文书
从事会计工作年限证明
2015/06/23 职场文书
校园音乐节目广播稿
2015/08/19 职场文书