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 相关文章推荐
JS中style属性
Oct 11 Javascript
jquery 之 $().hover(func1, funct2)使用方法
Jun 14 Javascript
使用js解决由border属性引起的div宽度问题
Nov 26 Javascript
jQuery插件MixItUp实现动画过滤和排序
Apr 12 Javascript
js仿QQ中对联系人向左滑动、滑出删除按钮的操作
Apr 07 Javascript
Jquery元素追加和删除的实现方法
May 24 Javascript
理解javascript中的闭包
Jan 11 Javascript
JS与jQuery实现子窗口获取父窗口元素值的方法
Apr 17 jQuery
JavaScript实现的超简单计算器功能示例
Dec 23 Javascript
js实现移动端tab切换时下划线滑动效果
Sep 08 Javascript
Ant Design Vue table中列超长显示...并加提示语的实例
Oct 31 Javascript
JS前端使用Canvas快速实现手势解锁特效
Sep 23 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
我的论坛源代码(八)
2006/10/09 PHP
PHP 数据结构 算法描述 冒泡排序 bubble sort
2011/07/10 PHP
php中替换字符串中的空格为逗号','的方法
2014/06/09 PHP
php实现转换html格式为文本格式的方法
2016/05/16 PHP
laravel通过创建自定义artisan make命令来新建类文件详解
2017/08/17 PHP
纯CSS打造的导航菜单(附jquery版)
2010/08/07 Javascript
使用原生javascript创建通用表单验证——更锋利的使用dom对象
2011/09/13 Javascript
点击按钮或链接不跳转只刷新页面的脚本整理
2013/10/22 Javascript
在每个匹配元素的外部插入新元素的方法
2013/12/20 Javascript
js控制div弹出层实现方法
2015/05/11 Javascript
jQuery实现的仿百度分页足迹效果代码
2015/10/30 Javascript
JavaScript与HTML的结合方法详解
2015/11/23 Javascript
JavaScript获取客户端IP的方法(新方法)
2016/03/11 Javascript
JavaScript自学笔记(必看篇)
2016/06/23 Javascript
jQuery获取table行数并输出单元格内容的实现方法
2016/06/30 Javascript
js 实现一些跨浏览器的事件方法详解及实例
2016/10/27 Javascript
Javascript实现数组中的元素上下移动
2017/04/28 Javascript
利用Javascript实现一套自定义事件机制
2017/12/14 Javascript
Material(包括Material Icon)在Angular2中的使用详解
2018/02/11 Javascript
Vue实现点击按钮复制文本内容的例子
2019/11/09 Javascript
OpenLayers3实现测量功能
2020/09/25 Javascript
Python文件操作基本流程代码实例
2017/12/11 Python
基于Python实现大文件分割和命名脚本过程解析
2019/09/29 Python
Python动态导入模块和反射机制详解
2020/02/18 Python
python开发实例之python使用Websocket库开发简单聊天工具实例详解(python+Websocket+JS)
2020/03/18 Python
Python之字典添加元素的几种方法
2020/09/30 Python
python 基于wx实现音乐播放
2020/11/24 Python
Django中日期时间型字段进行年月日时分秒分组统计
2020/11/27 Python
对pytorch中x = x.view(x.size(0), -1) 的理解说明
2021/03/03 Python
运动会开幕式邀请函
2014/02/03 职场文书
团结演讲稿范文
2014/05/23 职场文书
个人承诺书格式
2014/06/03 职场文书
经验交流材料格式
2014/12/30 职场文书
2015年社区科普工作总结
2015/05/13 职场文书
高中诗歌鉴赏教学反思
2016/02/16 职场文书
SQL试题 使用窗口函数选出连续3天登录的用户
2022/04/24 Oracle