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报错 Object doesn't support this property or method的原因分析
Mar 31 Javascript
Table冻结表头示例代码
Aug 20 Javascript
Jquery结合HTML5实现文件上传
Jun 25 Javascript
js实现的简洁网页滑动tab菜单效果代码
Aug 24 Javascript
input点击后placeholder中的提示消息消失
Jan 15 Javascript
RequireJS多页面应用实例分析
Jun 29 Javascript
VueJS全面解析
Nov 10 Javascript
Vue 过渡(动画)transition组件案例详解
Jan 22 Javascript
JavaScript之面向对象_动力节点Java学院整理
Jun 29 Javascript
vue2.0 常用的 UI 库实例讲解
Dec 12 Javascript
JS运动改变单物体透明度的方法分析
Jan 23 Javascript
ES6 更易于继承的类语法的使用
Feb 11 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
删除无限分类并同时删除它下面的所有子分类的方法
2010/08/08 PHP
php设计模式 Factory(工厂模式)
2011/06/26 PHP
php mail to 配置详解
2014/01/16 PHP
Linux下php5.4启动脚本
2014/08/03 PHP
php自定义加密与解密程序实例
2014/12/31 PHP
如何在HTML 中嵌入 PHP 代码
2015/05/13 PHP
PHP实现生成数据字典功能示例
2018/05/24 PHP
php实现算术验证码功能
2018/12/05 PHP
JavaScript脚本性能优化注意事项
2008/11/18 Javascript
IE6下通过a标签点击切换图片的问题
2010/11/14 Javascript
JavaScript实现x秒后自动跳转到一个页面
2013/01/03 Javascript
10个基于浏览器的JavaScript调试工具分享
2013/02/07 Javascript
angularjs实现与服务器交互分享
2014/06/24 Javascript
javascript中 try catch用法
2015/08/16 Javascript
JS采用绝对定位实现回到顶部效果完整实例
2016/06/20 Javascript
jQuery继承extend用法详解
2016/10/10 Javascript
Angular4实现动态添加删除表单输入框功能
2017/08/11 Javascript
详解自定义ajax支持跨域组件封装
2018/02/08 Javascript
layer更改皮肤的实现方法
2019/09/11 Javascript
vue父子模板传值问题解决方法案例分析
2020/02/26 Javascript
为什么推荐使用JSX开发Vue3
2020/12/28 Vue.js
[48:00]完美世界DOTA2联赛循环赛 Forest vs Inki BO2第二场 11.04
2020/11/04 DOTA
[50:38]DOTA2-DPC中国联赛 正赛 Phoenix vs CDEC BO3 第二场 3月7日
2021/03/11 DOTA
Python处理字符串之isspace()方法的使用
2015/05/19 Python
python根据日期返回星期几的方法
2015/07/06 Python
利用python获取Ping结果示例代码
2017/07/06 Python
flask入门之文件上传与邮件发送示例
2018/07/18 Python
python 解决动态的定义变量名,并给其赋值的方法(大数据处理)
2018/11/10 Python
深入了解Python在HDA中的应用
2019/09/05 Python
python pandas移动窗口函数rolling的用法
2020/02/29 Python
python七种方法判断字符串是否包含子串
2020/08/18 Python
python unichr函数知识点总结
2020/12/16 Python
使用canvas绘制贝塞尔曲线
2014/12/17 HTML / CSS
大学生个人学年总结
2015/02/15 职场文书
“5.12”护士节主持词
2015/07/04 职场文书
小学运动会入场词
2015/07/18 职场文书