vue和better-scroll实现列表左右联动效果详解


Posted in Javascript onApril 29, 2019

一.实现思路

  1. (1)实现上是左右分别一个better-scroll列表
  2. (2)利用计算右侧列表每一个大区块的高度来计算左侧的位置

二.实现

1.实现左右两个better-scroll

(1)dom结构(better-scroll要求,会把最外层dom的第一个子元素作为要滚动的区域)

左边滚动列表dom
 <div class="menu-wrapper" v-el:menu-wrapper>
   <ul>
    <li v-for="item in goods" class="menu-item"
      :class="{'current':currentIndex === $index}"
      @click="selectMenu($index,$event)">
     <span class="text border-1px">
      <span v-show="item.type > 0" class="icon"
       :class="classMap[item.type]"></span>{{item.name}}
     </span>
    </li>
   </ul>
  </div>

右边滚动列表dom
<div class="food-wrapper" v-el:food-wrapper>
   <ul>
    <li v-for="item in goods" class="food-list food-list-hook">
     <h1 class="title">{{item.name}}</h1>
     <ul>
      <li v-for="food in item.foods" class="food-item border-1px">
       <div class="icon">
        <img width="57" height="57" :src="food.icon">
       </div>
       <div class="content">
        <h2 class="name">{{food.name}}</h2>
        <p class="desc">{{food.description}}</p>
        <div class="extra">
         <span class="count">月售{{food.sellCount}}份</span>
         <span>好评率{{food.rating}}%</span>
         <div class="price">
          <span class="now">¥{{food.price}}</span>
          <span class="old" v-show="food.oldPrice">¥{{food.oldPrice}}</span>
         </div>
        </div>
       </div>
      </li>
     </ul>
    </li>
   </ul>
  </div>

在数据请求完成后的$nextTick中初始化better-scroll,就能实现两个列表分别能滚动,至于联动,要后面自己做

_initScroll() {
    this.menuScroll = new BScroll(this.$els.menuWrapper,{
     click:true  //允许better-scroll列表上的点击事件
    });
    this.foodsScroll = new BScroll(this.$els.foodWrapper,{
     probeType : 3  //让better-scroll监听scroll事件
    });
    this.foodsScroll.on('scroll',(pos) => {
     this.scrollY =Math.abs(Math.round(pos.y));
    })
   },

2.实现联动效果

(1)具体的联动实现思路

  1. 在渲染完成后($nextTick内),初始化better-scroll,并在初始化函数内添加右侧列表的scroll监听事件,并记录scrollY值到,存入vue的data中
  2. 在渲染完成后($nextTick内),计算右侧列表的每一个大区块的高度,并累加,存入数组listHeight
  3. 因为scrollY值在滚动中总是不断变化的,所以在computed中计算出currentIndex,当前滚动区域是哪一个大区块,也就是listHeight数组的下标
  4. 在dom中根据currentIndex应用左侧列表被点中的样式
  5. 在左侧列表某一项被点中的时候,右侧列表滑动到某一个大块区域,
//初始化better-scroll
_initScroll() {
    this.menuScroll = new BScroll(this.$els.menuWrapper,{
     click:true
    });
    this.foodsScroll = new BScroll(this.$els.foodWrapper,{
     probeType : 3
    });
    this.foodsScroll.on('scroll',(pos) => {
     this.scrollY =Math.abs(Math.round(pos.y));
    })
   },
_calculateHeight() {
    let foodList = this.$els.foodWrapper.getElementsByClassName("food-list-hook");
    let height = 0;
    this.listHeight.push(height);
    for(let i=0;i<foodList.length;i++) {
     let item = foodList[i];
     height += item.clientHeight;
     this.listHeight.push(height);
    }
   }
computed: {
   currentIndex() {
    for(let i=0;i< this.listHeight.length;i++) {
     let height1 = this.listHeight[i];
     let height2 = this.listHeight[i+1];
     if(!height2 || (this.scrollY >= height1 && this.scrollY < height2)){
      return i;
     }
    }
    return 0;
   }
  },
<div class="menu-wrapper" v-el:menu-wrapper>
   <ul>
    <!-- :class="{'current':currentIndex === $index}" 就是根据currentIndex应用左侧列表被点中的样式 -->
    <li v-for="item in goods" class="menu-item"
      :class="{'current':currentIndex === $index}"
      @click="selectMenu($index,$event)">
     <span class="text border-1px">
      <span v-show="item.type > 0" class="icon"
       :class="classMap[item.type]"></span>{{item.name}}
     </span>
    </li>
   </ul>
  </div>
//被点击事件
//dom
<div class="menu-wrapper" v-el:menu-wrapper>
   <ul>
    <!-- @click="selectMenu($index,$event)" 就是点击事件 -->
    <li v-for="item in goods" class="menu-item"
      :class="{'current':currentIndex === $index}"
      @click="selectMenu($index,$event)">
     <span class="text border-1px">
      <span v-show="item.type > 0" class="icon"
       :class="classMap[item.type]"></span>{{item.name}}
     </span>
    </li>
   </ul>
  </div>
//js  
selectMenu(index,event) {
    if(!event._constructed) {
     return ;
    }
    let foodList = this.$els.foodWrapper.getElementsByClassName("food-list-hook");
    let el = foodList[index];
    this.foodsScroll.scrollToElement(el,300);
   },

以上所述是小编给大家介绍的vue和better-scroll实现列表左右联动效果详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
JS小框架 fly javascript framework
Nov 26 Javascript
修改jquery里的dialog对话框插件为框架页(iframe) 的方法
Sep 14 Javascript
jquery 实现checkbox全选,反选,全不选等功能代码(奇数)
Oct 24 Javascript
jquery实现智能感知连接外网搜索
May 21 Javascript
让网页跳转到指定位置的jquery代码非书签
Sep 06 Javascript
Javascript call和apply区别及使用方法
Nov 14 Javascript
javascript监听鼠标滚轮事件浅析
Jun 05 Javascript
bootstrap table 服务器端分页例子分享
Feb 10 Javascript
JavaScript实现点击文本自动定位到下拉框选中操作
Jun 15 Javascript
node中Express 动态设置端口的方法
Aug 04 Javascript
基于vue,vue-router, vuex及addRoutes进行权限控制问题
May 02 Javascript
JS字符串常用操作方法实例小结
Jun 24 Javascript
Vue 引入AMap高德地图的实现代码
Apr 29 #Javascript
微信小程序--获取用户地理位置名称(无须用户授权)的方法
Apr 29 #Javascript
Vuejs学习笔记之使用指令v-model完成表单的数据双向绑定
Apr 29 #Javascript
微信小程序-form表单提交代码实例
Apr 29 #Javascript
vue在index.html中引入静态文件不生效问题及解决方法
Apr 29 #Javascript
微信小程序传值以及获取值方法的详解
Apr 29 #Javascript
小程序封装wx.request请求并创建接口管理文件的实现
Apr 29 #Javascript
You might like
php魔术变量用法实例详解
2014/11/13 PHP
php foreach如何跳出两层循环(详解)
2016/11/05 PHP
多个Laravel项目如何共用migrations详解
2018/09/25 PHP
20个非常有用的PHP类库 加速php开发
2010/01/15 Javascript
javascript 数组学习资料收集
2010/04/11 Javascript
客户端 使用XML DOM加载json数据的方法
2010/09/28 Javascript
(跨浏览器基础事件/浏览器检测/判断浏览器)经验代码分享
2013/01/24 Javascript
控制文字内容的显示与隐藏示例
2014/06/11 Javascript
JS图片放大效果简单实现代码
2016/09/08 Javascript
Vue和Bootstrap的整合思路详解
2017/06/30 Javascript
微信小程使用swiper组件实现图片轮播切换显示功能【附源码下载】
2017/12/12 Javascript
详解如何用babel转换es6的class语法
2018/04/03 Javascript
node.js 基于cheerio的爬虫工具的实现(需要登录权限的爬虫工具)
2019/04/10 Javascript
使用nodejs分离html文件里的js和css详解
2019/04/12 NodeJs
浅谈webpack 四个核心概念之Entry
2019/06/12 Javascript
layui富文本编辑器前端无法取值的解决方法
2019/09/18 Javascript
js判断密码强度的方法
2020/03/18 Javascript
Python基于有道实现英汉字典功能
2015/07/25 Python
Tensorflow实现卷积神经网络的详细代码
2018/05/24 Python
Django url,从一个页面调到另个页面的方法
2019/08/21 Python
python 利用pyttsx3文字转语音过程详解
2019/09/25 Python
python实现图片横向和纵向拼接
2020/03/05 Python
Python使用Opencv实现边缘检测以及轮廓检测的实现
2020/12/31 Python
HTML5样式控制示例代码
2013/11/27 HTML / CSS
阿联酋电子产品购物网站:Menakart
2017/09/15 全球购物
Skyscanner加拿大:全球旅行搜索平台
2018/11/19 全球购物
Kathmandu新西兰官网:新西兰户外运动品牌
2019/07/27 全球购物
枚举与#define宏的区别
2014/04/30 面试题
俄语翻译实习生的自我评价分享
2013/11/06 职场文书
质量月口号
2014/06/20 职场文书
2015年汽车销售经理工作总结
2015/04/27 职场文书
大学开学典礼新闻稿
2015/07/17 职场文书
田径运动会广播稿
2015/08/19 职场文书
2016关于军训的心得体会
2016/01/11 职场文书
Java spring定时任务详解
2021/10/05 Java/Android
MySQL添加索引特点及优化问题
2022/07/23 MySQL