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 07 Javascript
关于Javascript作用域链的八点总结
Dec 06 Javascript
jQuery简单获取键盘事件的方法
Jan 22 Javascript
纯js实现手风琴效果
Apr 17 Javascript
jQuery实现指定区域外单击关闭指定层的方法【经典】
Jun 22 Javascript
js实现点击按钮弹出上传文件的窗口
Dec 23 Javascript
浅谈angular2路由预加载策略
Oct 04 Javascript
webpack多入口文件页面打包配置详解
Jan 09 Javascript
详解JavaScript实现动态的轮播图效果
Apr 29 Javascript
微信小程序实现3D轮播图效果(非swiper组件)
Sep 21 Javascript
深度解读vue-resize的具体用法
Jul 08 Javascript
JS相册图片抖动放大展示效果的示例代码
Jan 29 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通过iconv将字符串从GBK转换为UTF8字符集
2011/07/18 PHP
LotusPhp笔记之:Cookie组件的使用详解
2013/05/06 PHP
PHP 验证码不显示只有一个小红叉的解决方法
2013/09/30 PHP
ThinkPHP3.1新特性之对Ajax的支持更加完善
2014/06/19 PHP
php中使用base HTTP验证的方法
2015/04/20 PHP
PC端微信扫码支付成功之后自动跳转php版代码
2017/07/07 PHP
Alliance vs Liquid BO3 第二场2.13
2021/03/10 DOTA
创建一个复制UBB软件信息的链接或按钮的js代码
2008/01/06 Javascript
js程序中美元符号$是什么
2008/06/05 Javascript
Javscript删除数组中指定元素并返回新数组
2014/03/06 Javascript
JavaScript实现动态创建CSS样式规则方案
2014/09/06 Javascript
jQuery实现“扫码阅读”功能
2015/01/21 Javascript
网页收藏夹显示ICO图标(代码少)
2015/08/04 Javascript
Jquery和BigFileUpload实现大文件上传及进度条显示
2016/06/27 Javascript
HTML5 实现的一个俄罗斯方块实例代码
2016/09/19 Javascript
vue bootstrap小例子一枚
2017/06/09 Javascript
three.js中文文档学习之如何本地运行详解
2017/11/20 Javascript
vux uploader 图片上传组件的安装使用方法
2018/05/15 Javascript
VSCode launch.json配置详细教程
2020/06/18 Javascript
[02:54]DOTA2英雄基础教程 暗影牧师戴泽
2013/12/05 DOTA
发布你的Python模块详解
2016/09/15 Python
virtualenv实现多个版本Python共存
2017/08/21 Python
python3安装pip3(install pip3 for python 3.x)
2018/04/03 Python
python 定义类时,实现内部方法的互相调用
2019/12/25 Python
Python SQLAlchemy库的使用方法
2020/10/13 Python
Python命令行参数argv和argparse该如何使用
2021/02/08 Python
CSS3实现头像旋转效果
2017/03/13 HTML / CSS
浅谈HTML5 服务器推送事件(Server-sent Events)
2017/08/01 HTML / CSS
个人贷款承诺书
2014/03/28 职场文书
干部个人对照检查材料
2014/08/25 职场文书
试用期转正员工自我评价
2014/09/18 职场文书
法律讲堂观后感
2015/06/11 职场文书
2016大学迎新晚会开场白
2015/11/24 职场文书
闭幕词的写作格式与范文!
2019/06/24 职场文书
仅用一句SQL更新整张表的涨跌幅、涨跌率的解决方案
2021/05/06 MySQL
利用python实时刷新基金估值(摸鱼小工具)
2021/09/15 Python