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 相关文章推荐
Jquery判断IE6等浏览器的代码
Apr 05 Javascript
MooTools 页面滚动浮动层智能定位实现代码
Aug 23 Javascript
图片在浏览器中底部对齐 解决方法之一
Nov 30 Javascript
了解了这些才能开始发挥jQuery的威力
Oct 10 Javascript
Extjs Label的 fieldLabel和html属性值对齐的方法
Jun 15 Javascript
javascript中的Function.prototye.bind
Jun 25 Javascript
HTML5+jQuery实现搜索智能匹配功能
Mar 24 jQuery
jquery实现图片上传前本地预览
Apr 28 jQuery
JavaScript格式化json和xml的方法示例
Jan 22 Javascript
webpack3升级到webpack4遇到问题总结
Sep 30 Javascript
ckeditor一键排版功能实现方法分析
Feb 06 Javascript
jQuery实现移动端下拉展现新的内容回弹动画
Jun 24 jQuery
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
一个域名查询的程序
2006/10/09 PHP
CI框架表单验证实例详解
2016/11/21 PHP
php读取XML的常见方法实例总结
2017/04/25 PHP
PHP从数组中删除元素的四种方法实例
2017/05/12 PHP
php实现生成code128条形码的方法详解
2017/07/19 PHP
PHP unlink与rmdir删除目录及目录下所有文件实例代码
2018/02/07 PHP
动态的改变IFrame的高度实现IFrame自动伸展适应高度
2012/12/28 Javascript
JS画线(实例代码)
2013/11/20 Javascript
Jquery中children与find之间的区别详细解析
2013/11/29 Javascript
JS delegate与live浅析
2013/12/21 Javascript
一张表格告诉你windows.onload()与$(document).ready()的区别
2014/05/16 Javascript
js中直接声明一个对象的方法
2014/08/10 Javascript
全面解析JavaScript的Backbone.js框架中的Router路由
2016/05/05 Javascript
bootstrap fileinput完整实例分享
2016/11/08 Javascript
jquery实现轮播图效果
2017/02/13 Javascript
ReactNative Image组件使用详解
2017/08/07 Javascript
React实践之Tree组件的使用方法
2017/09/30 Javascript
微信小程序实现底部导航
2018/11/05 Javascript
jQuery基于随机数解决中午吃什么去哪吃问题示例
2018/12/29 jQuery
使用typescript快速开发一个cli的实现示例
2020/12/09 Javascript
Element-ui upload上传文件限制的解决方法
2021/01/22 Javascript
[00:10]DOTA2全国高校联赛速递
2018/05/30 DOTA
pandas.DataFrame选取/排除特定行的方法
2018/07/03 Python
Python实现输入二叉树的先序和中序遍历,再输出后序遍历操作示例
2018/07/27 Python
PyCharm MySQL可视化Database配置过程图解
2020/06/09 Python
python 元组的使用方法
2020/06/09 Python
CSS3 优势以及网页设计师如何使用CSS3技术
2009/07/29 HTML / CSS
HTML5 canvas基本绘图之填充样式实现
2016/06/27 HTML / CSS
详解webapp页面滚动卡顿的解决办法
2018/12/26 HTML / CSS
违反课堂纪律检讨书
2014/01/19 职场文书
美容院考勤制度
2014/01/30 职场文书
教师节促销方案
2014/03/22 职场文书
婚前协议书范本
2014/04/15 职场文书
2014年乡镇安全生产工作总结
2014/12/02 职场文书
迎新生晚会主持词
2015/06/30 职场文书
几款流行的HTML5 UI框架比较(小结)
2021/04/08 HTML / CSS