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 学习笔记 防止发生命名冲突
Jul 30 Javascript
IE6下通过a标签点击切换图片的问题
Nov 14 Javascript
js 剪切板的用法(clipboardData.setData)与js match函数介绍
Nov 19 Javascript
Angular1.x复杂指令实例详解
Mar 01 Javascript
原生JS改变透明度实现轮播效果
Mar 24 Javascript
浅谈对Angular中的生命周期钩子的理解
Jul 31 Javascript
利用VS Code开发你的第一个AngularJS 2应用程序
Dec 15 Javascript
redux中间件之redux-thunk的具体使用
Apr 17 Javascript
layUI实现三级导航菜单效果
Jul 26 Javascript
让Vue响应Map或Set的变化操作
Nov 11 Javascript
JS实现超级好看的鼠标小尾巴特效
Dec 01 Javascript
使用vue判断当前环境是安卓还是IOS
Apr 12 Vue.js
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桌面中心(一) 创建数据库
2007/03/11 PHP
PHP最常用的ini函数分析 针对PHP.ini配置文件
2010/04/22 PHP
php设计模式 Proxy (代理模式)
2011/06/26 PHP
PHP中static关键字原理的学习研究分析
2011/07/18 PHP
PHP采用XML-RPC构造Web Service实例教程
2014/07/16 PHP
PHP学习笔记之php文件操作
2016/06/03 PHP
php利用云片网实现短信验证码功能的示例代码
2017/11/18 PHP
用roll.js实现的图片自动滚动+鼠标触动的特效
2007/03/18 Javascript
JavaScript prototype属性使用说明
2010/05/13 Javascript
javascript小组件 原生table排序表格脚本(兼容ie firefox opera chrome)
2012/07/25 Javascript
提示$ is not defined错误分析及解决
2013/04/09 Javascript
js 限制input只能输入数字、字母和汉字等等
2013/12/18 Javascript
javascript 中that的含义示例介绍
2014/05/14 Javascript
javascript实现的固定位置悬浮窗口实例
2015/04/30 Javascript
借助FileReader实现将文件编码为Base64后通过AJAX上传
2015/12/24 Javascript
js鼠标单击和双击事件冲突问题的快速解决方法
2016/07/11 Javascript
让你彻底掌握es6 Promise的八段代码
2017/07/26 Javascript
微信小程序收藏功能的实现代码
2018/06/12 Javascript
微信小程序实现多行文字超出部分省略号显示功能
2019/10/23 Javascript
vue2.x数组劫持原理的实现
2020/04/19 Javascript
Vue 禁用浏览器的前进后退操作
2020/09/04 Javascript
elementui实现预览图片组件二次封装
2020/12/29 Javascript
使用AutoJs实现微信抢红包的代码
2020/12/31 Javascript
Python创建二维数组实例(关于list的一个小坑)
2017/11/07 Python
Django csrf 验证问题的实现
2018/10/09 Python
Python UnboundLocalError和NameError错误根源案例解析
2018/10/31 Python
手机配件第一品牌:ZAGG
2017/05/28 全球购物
J2EE包括哪些技术
2016/11/25 面试题
专家推荐信模板
2014/05/09 职场文书
社团活动总结书
2014/06/27 职场文书
2014年合同管理工作总结
2014/12/02 职场文书
生产现场禁烟通知
2015/04/23 职场文书
消防演习通知
2015/04/25 职场文书
2016年党员干部公开承诺书
2016/03/24 职场文书
某药房的新员工入职告知书!
2019/07/15 职场文书
python3 sqlite3限制条件查询的操作
2021/04/07 Python