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判断ie浏览器6/7版本加载不同样式表的实现代码
Dec 26 Javascript
JS获取URL中的参数数据
Dec 05 Javascript
jquery无法设置checkbox选中即没有变成选中状态
Mar 27 Javascript
Node.js中的模块机制学习笔记
Nov 04 Javascript
window.onerror()的用法与实例分析
Jan 27 Javascript
JavaScript动态检验密码强度的实现方法
Nov 09 Javascript
详解网站中图片日常使用以及优化手法
Jan 09 Javascript
Vue全局分页组件的实现代码
Aug 10 Javascript
vue路由跳转传参数的方法
May 06 Javascript
arctext.js实现文字平滑弯曲弧形效果的插件
May 13 Javascript
JavaScript剩余操作符Rest Operator详解
Jul 20 Javascript
layUI的验证码功能及校验实例
Oct 25 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
基于 Swoole 的微信扫码登录功能实现代码
2018/01/15 PHP
阿里云Win2016安装Apache和PHP环境图文教程
2018/03/11 PHP
sliderToggle在写jquery的计时器setTimeouter中不生效
2014/05/26 Javascript
$(document).ready(function() {})不执行初始化脚本
2014/06/19 Javascript
javascript实现多级联动下拉菜单的方法
2015/02/06 Javascript
使用CSS+JavaScript或纯js实现半透明遮罩效果的实例分享
2016/05/09 Javascript
jQuery插件简单学习实例教程
2016/07/01 Javascript
微信小程序 利用css实现遮罩效果实例详解
2017/01/21 Javascript
使用JS 插件qrcode.js生成二维码功能
2017/02/20 Javascript
详解Vue.js入门环境搭建
2017/03/17 Javascript
ES6正则表达式扩展笔记
2017/07/25 Javascript
ligerUI---ListBox(列表框可移动的实例)
2017/11/28 Javascript
Vue项目中如何引入icon图标
2018/03/28 Javascript
20个最常见的jQuery面试问题及答案
2018/05/23 jQuery
Vuex持久化插件(vuex-persistedstate)解决刷新数据消失的问题
2019/04/16 Javascript
js设置默认时间跨度过程详解
2019/07/17 Javascript
JS实现图片切换特效
2019/12/23 Javascript
vue搜索页开发实例代码详解(热门搜索,历史搜索,淘宝接口演示)
2020/04/11 Javascript
js实现表格单列按字母排序
2020/08/12 Javascript
如何在 Vue 中使用 JSX
2021/02/14 Vue.js
[01:30:55]VG vs Mineski Supermajor 败者组 BO3 第三场 6.6
2018/06/07 DOTA
[00:48]DOTA2国际邀请赛公开赛报名开始 扫码开启逐梦之旅
2018/06/06 DOTA
Python 抓取动态网页内容方案详解
2014/12/25 Python
点球小游戏python脚本
2018/05/22 Python
python3+requests接口自动化session操作方法
2018/10/13 Python
python控制nao机器人身体动作实例详解
2019/04/29 Python
解决django FileFIELD的编码问题
2020/03/30 Python
英国领先的维生素和营养补充剂直接供应商:Healthspan
2019/04/22 全球购物
俄罗斯珠宝市场的领导者之一:Бронницкий ювелир
2019/10/02 全球购物
大学自主招生自荐信
2013/12/16 职场文书
城市规划应届生推荐信
2014/09/08 职场文书
领导班子遵守党的政治纪律情况对照检查材料
2014/09/26 职场文书
2014年检验员工作总结
2014/11/19 职场文书
2014社区健康教育工作总结
2014/12/16 职场文书
2019假期福利管理制度!
2019/07/15 职场文书
如何解决goland,idea全局搜索快捷键失效问题
2022/04/03 Golang