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 相关文章推荐
JavaScript 异步调用框架 (Part 6 - 实例 &amp; 模式)
Aug 04 Javascript
url 编码 js url传参中文乱码解决方案
Apr 11 Javascript
基于jquery跨浏览器显示的file上传控件
Oct 24 Javascript
jquery实现图片等比例缩放以及max-width在ie中不兼容解决
Mar 21 Javascript
JS实现带有3D立体感的银灰色竖排折叠菜单代码
Oct 20 Javascript
jQuery随手笔记之常用的jQuery操作DOM事件
Nov 29 Javascript
全面解析Bootstrap中nav、collapse的使用方法
May 22 Javascript
浅谈JavaScript前端开发的MVC结构与MVVM结构
Jun 03 Javascript
Django与Vue语法的冲突问题完美解决方法
Dec 14 Javascript
再谈Angular4 脏值检测(性能优化)
Apr 23 Javascript
js比较两个单独的数组或对象是否相等的实例代码
Apr 28 Javascript
vue中el-input绑定键盘按键(按键修饰符)
Jul 22 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/05/29 PHP
PHP 循环删除无限分类子节点的实现代码
2013/06/21 PHP
几道坑人的PHP面试题 试试看看你会不会也中招
2014/08/19 PHP
PHP内部实现打乱字符串顺序函数str_shuffle的方法
2019/02/14 PHP
PHP7变量处理机制修改
2021/03/09 PHP
newxtree.js代码
2007/03/13 Javascript
javascript 鼠标滚轮事件
2009/04/09 Javascript
javascript抖动元素的小例子
2013/10/28 Javascript
javascript函数中参数传递问题示例探讨
2014/07/31 Javascript
超链接的禁用属性Disabled使用示例
2014/07/31 Javascript
JS 组件系列之Bootstrap Table 冻结列功能IE浏览器兼容性问题解决方案
2017/06/30 Javascript
Vue-router路由判断页面未登录跳转到登录页面的实例
2017/10/26 Javascript
vue结合axios与后端进行ajax交互的方法
2018/07/06 Javascript
微信小程序实现之手势锁功能实例代码
2018/07/19 Javascript
vue基于element-ui的三级CheckBox复选框功能的实现代码
2018/10/15 Javascript
详解vue-cli 脚手架 安装
2019/04/16 Javascript
微信小程序如何利用getCurrentPages进行页面传值
2019/07/01 Javascript
Python的Twisted框架上手前所必须了解的异步编程思想
2016/05/25 Python
python 中文件输入输出及os模块对文件系统的操作方法
2018/08/27 Python
Python3 pip3 list 出现 DEPRECATION 警告的解决方法
2019/02/16 Python
python3.x实现base64加密和解密
2019/03/28 Python
python语言的优势是什么
2020/06/17 Python
python元组拆包实现方法
2021/02/28 Python
bareMinerals官网:矿物质化妆品和护肤品
2018/02/04 全球购物
斯洛伐克家具和时尚装饰品购物网站:Butlers.sk
2019/09/08 全球购物
shell程序如何生命变量?shell变量是弱变量吗?
2014/11/10 面试题
材料化学应届生求职信
2013/10/09 职场文书
个人素质的自我评价分享
2013/12/16 职场文书
18岁生日感言
2014/01/12 职场文书
高中政治教学反思
2014/01/18 职场文书
教师自我剖析材料(四风问题)
2014/09/30 职场文书
大学生见习报告总结
2014/11/04 职场文书
2015年元旦促销方案书
2014/12/09 职场文书
2014年精神文明工作总结
2014/12/23 职场文书
彻底理解golang中什么是nil
2021/04/29 Golang
Java实战之用Swing实现通讯录管理系统
2021/06/13 Java/Android