Vue项目中使用better-scroll实现一个轮播图自动播放功能


Posted in Javascript onDecember 03, 2018

前言

better-scroll是一个非常非常强大的第三方库 在移动端利用这个库 不仅可以实现一个非常类似原生ScrollView的效果 也可以实现一个轮播图的效果 这里就先记录一下自己实现这个效果的一些过程吧

思路

1.首先要确定自己的HTML结构 基本结构就是一个wrapper包含一个content

2.其次需要明白的一个页面可以滚动的原理在于 当内容的高度超出了容器的高度才可以实现滚动 如果没有超出 那么就没有滚动的必要 因此第一点需要实现的就是 获取到所有内容的高度 由于实现的是一个轮播图 所以其实整个页面应该想象成这样

Vue项目中使用better-scroll实现一个轮播图自动播放功能

滚动原理

这里可以很清楚的看到 当页面的横向宽度超出了视口的宽度 因此也就可以实现滚动 综上所述 可以看出 实现横向轮播最重要的一点在于宽度 因此 我们首先要获得的就是整个轮播图的宽度

3.既然是个轮播图 那么用户同时也需要知道的就是 当前播放的是第几张图 也就是常见的"小白点" 小白点的个数用于告诉用户总共有几张图 而当前播放第几张图则可以在小白点上加上一些特殊样式的方法来告知用户

4.轮播图也需要一些常见的属性 例如 页面渲染以后自动播放以及播放间隔 还有一个就是 是否支持循环轮播

理清思路以后 就可以开始干活了 1.完善HTML结构 其实代码非常简单 也就是创建两个div 并且添加ref引用可以方便的通过ref属性获取上下文

<div class="slider"
 ref="slider">
 <div class="slider-content"
  ref="sliderContent">
 <slot></slot>
 </div>
</div>

这里用了vue中非常常见的slot插槽 为的是当我们在外部调用这个slider组件的时候 可以方便的在外部传入一些子组件

2.上文已经提到了一些控制slider的属性 所以需要在组件的props里接受这些属性 便于我们在外部方便的控制这些属性

props: {
 // 是否循环播放
 loop: {
 type: Boolean,
 default: true
 },
 // 是否自动播放
 autoPlay: {
 type: Boolean,
 default: true
 },
 // 播放间隔
 interval: {
 type: Number,
 default: 3000
 }
 }

3.一些初始步骤的完成的差不多了以后 我们需要借助到vue的一个生命周期钩子 mounted 也就是当页面渲染完毕以后 去获取轮播图的宽度以及初始化轮播图的一些设置

mounted: function () {
 setTimeout(() => {
 this.setSliderWidth()
 this.initSlider()
 }, 20)

这里有一个小小的tips 就是 通常情况下 浏览器渲染dom的时间为17ms 所以这里使用了一个延迟函数 在20ms以后去调用这些方法 也就是确保浏览器的dom被正确渲染 防止出现一些问题

4.上面只是调用了这个方法 还没有实现这些方法 首先在设置宽度的方法里 我们需要通过$refs.sliderContent拿到上下文 并且通过一个$refs.slider.clientWidth方法拿到当前屏幕宽度 然后遍历这个容器 取得容器里的所有内容 同时把获取的内容宽度设置为这个屏幕的宽度 最后所有的内容的宽度相加 就可以得到整个slider的宽度 说了这么多 感觉很绕口 所以还是看下代码吧

// 设置slider的宽度
 setSliderWidth: function (isResize) {
 // 获取slider里的所有的子元素
 this.children = this.$refs.sliderContent.children
 // console.log(this.children)
 // 计算宽度 = 图片个数+每张图片的宽度
 let width = 0
 // 获取手机屏幕的宽度
 let sliderWidth = this.$refs.slider.clientWidth
 
 for (let i = 0; i < this.children.length; i++) {
 // 获取children里的每一项内容 
 let child = this.children[i]
 
 child.style.width = sliderWidth + 'px'
 width += sliderWidth
 }
 if (this.loop) {
 width += 2 * sliderWidth
 }
 this.$refs.sliderContent.style.width = width + 'px'
 }

这样我们就获取了整个slider的宽度 还有一个细节在于 当如果是loop的时候 better-scroll会在头尾克隆两份 所以宽度会需要*2 接下去就是实现一些初始化better-scroll的一些配置了 具体的参数内容可以从better-scorll官网上查询到 这里就不多做赘述了

// 设置宽度以后初始化slider
 initSlider: function () {
 this.slider = new BScroll(this.$refs.slider, {
 scrollX: true,
 scrollY: false,
 momentum: false,
 snap: {
  loop: this.loop,
  threshold: 0.3,
  speed: 400
 },
 click: true
 })
 }

5.实现上述两个方法以后 其实轮播图基本已经可以在页面上看到了 大概就是长成这样 不过这样写完以后 会发现轮播图是没有办法自动轮播的以及当前显示的是几张图的样式并没有正确显示 所以接下去就是实现这两个方法 ps:这里的图片数据来源什么 是请求了QQ音乐banner的接口文件

轮播图的效果

6.实现dots样式的正确加载 这里用到了vue中样式的绑定

<div class="dots">
 <span class="dot"
  v-for="(item, index) of dots"
  :class="{active:currentPageIndex === index}"
  :key="index">
 </span>
 </div>

也就是说 我们通过下标来绑定样式 同时监听一个better-scroll的'scrollEnd'事件 当滚动结束的时候调用getCurrentPage()这个方法 这个方法会有一个返回值pageX 也就是横向滚动到第几页 把这个返回值赋值给currentPageIndex 从而达到正确显示样式的目的

this.slider.on('scrollEnd', () => {
 let page = this.slider.getCurrentPage().pageX
 this.currentPageIndex = page
 // 当滚动结束以后 如果是自动播放的话 那么首先要清除定时器(防止手动拖动轮播图以后图片无法正确显示)然后再次执行方法 才能实现轮播
 if (this.autoPlay) {
  clearTimeout(this.timer)
  this.play()
 }
 })

7.实现自动播放功能 better-scroll也提供了一个接口goToPage(x, y, time, easing) 顾名思义也就是转到对应页面 其中几个参数分别代表 x表示横向页面 y表示纵向页面 time表示动画执行时间 easing一般不建议修改 有了这个接口 其实就非常轻松了 我们只需要在methods里再写一个Play方法 具体的思路就是 通过currentPageIndex+=1得到下一张要播放的图片的索引 同时当索引值达到图片数组的长度的时候将要索引重新赋值为0就好了 并在页面渲染了以后调用就可以了

play: function () {
 let playPage = this.currentPageIndex + 1
 if (playPage === this.children.length - 2) {
 playPage = 0
 }
 setTimeout(() => {
 this.slider.goToPage(playPage, 0, 400)
 }, this.interval)
 }

这里也有个细节就是 当设置这个轮播图为循环滚动的时候 better-scroll会自动在头尾各克隆一份图片 所以长度需要减去2 这样就可以实现轮播图的自动播放了

总结

以上所述是小编给大家介绍的Vue项目中使用better-scroll实现一个轮播图自动播放功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
jQuery EasyUI API 中文文档 - NumberSpinner数值微调器使用介绍
Oct 21 Javascript
js超时调用setTimeout和间歇调用setInterval实例分析
Jan 28 Javascript
跟我学习javascript的异步脚本加载
Nov 20 Javascript
jQuery EasyUI基础教程之EasyUI常用组件(推荐)
Jul 15 Javascript
用纯Node.JS弹出Windows系统消息提示框实例(MessageBox)
May 17 Javascript
Angular4学习之Angular CLI的安装与使用教程
Jan 04 Javascript
解决Vue 项目打包后favicon无法正常显示的问题
Sep 01 Javascript
深入理解JavaScript 箭头函数
May 30 Javascript
微信小程序实现轨迹回放的示例代码
Dec 13 Javascript
Openlayers实现图形绘制
Sep 28 Javascript
解决Antd Table表头加Icon和气泡提示的坑
Nov 17 Javascript
vue-calendar-component 封装多日期选择组件的实例代码
Dec 04 Vue.js
Vue.js 图标选择组件实践详解
Dec 03 #Javascript
vue-music 使用better-scroll遇到轮播图不能自动轮播问题
Dec 03 #Javascript
vue-cli3.0+element-ui上传组件el-upload的使用
Dec 03 #Javascript
利用jquery和BootStrap实现动态滚动条效果
Dec 03 #jQuery
微信小程序实现页面下拉刷新和上拉加载功能详解
Dec 03 #Javascript
微信小程序在地图选择地址并返回经纬度简单示例
Dec 03 #Javascript
vue.js实现的全选与全不选功能示例【基于elementui】
Dec 03 #Javascript
You might like
php实现从ftp服务器上下载文件树到本地电脑的程序
2009/02/10 PHP
php 表单提交大量数据发生丢失的解决方法
2014/03/03 PHP
Yii2 批量插入、更新数据实例
2017/03/15 PHP
thinkPHP+ajax实现统计页面pv浏览量的方法
2017/03/15 PHP
动态加载图片路径 保持JavaScript控件的相对独立性
2010/09/06 Javascript
一款jquery特效编写的大度宽屏焦点图切换特效的实例代码
2013/08/05 Javascript
jquery easyui 结合jsp简单展现table数据示例
2014/04/18 Javascript
js子页面获取父页面数据示例
2014/05/15 Javascript
JavaScript常用代码书写规范的超全面总结
2016/09/11 Javascript
Javascript highcharts 饼图显示数量和百分比实例代码
2016/12/06 Javascript
Vue按需加载的具体实现
2017/12/02 Javascript
详解vue.js之props传递参数
2017/12/12 Javascript
微信小程序获取当前时间及星期几的实例代码
2020/09/20 Javascript
python thread 并发且顺序运行示例
2009/04/09 Python
Python实现将16进制字符串转化为ascii字符的方法分析
2017/07/21 Python
zookeeper python接口实例详解
2018/01/18 Python
Python基于百度AI的文字识别的示例
2018/04/21 Python
python实现监控某个服务 服务崩溃即发送邮件报告
2018/06/21 Python
python生成n个元素的全组合方法
2018/11/13 Python
通过pycharm使用git的步骤(图文详解)
2019/06/13 Python
python读取图片的方式,以及将图片以三维数组的形式输出方法
2019/07/03 Python
Pytorch实现WGAN用于动漫头像生成
2021/03/04 Python
5分钟弄清楚html5的drag and drop(小结)
2019/04/10 HTML / CSS
浅谈利用缓存来优化HTML5 Canvas程序的性能
2015/05/12 HTML / CSS
努比亚手机官网:nubia
2016/10/06 全球购物
Corelle官方网站:购买康宁餐具
2016/11/02 全球购物
日本最大的药妆连锁店:Matsukiyo松本清药妆店
2017/11/23 全球购物
学生偷窃检讨书
2014/09/25 职场文书
乡镇遵守党的政治纪律情况对照检查材料
2014/09/26 职场文书
战略性融资合作协议书范本
2014/10/17 职场文书
民主评议党员工作总结
2014/10/20 职场文书
铁路安全反思材料
2014/12/24 职场文书
中学教师读书笔记
2015/07/01 职场文书
2016清明节森林防火广播稿
2015/12/17 职场文书
2016年党员创先争优承诺书
2016/03/25 职场文书
解决Python中的modf()函数取小数部分不准确问题
2021/05/28 Python