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 相关文章推荐
关于UTF-8的客户端用AJAX方式获取GB2312的服务器端乱码问题的解决办法
Nov 30 Javascript
Jquery获取元素的父容器对象示例代码
Feb 10 Javascript
我的Node.js学习之路(三)--node.js作用、回调、同步和异步代码 以及事件循环
Jul 06 Javascript
node.js中的fs.writeFile方法使用说明
Dec 14 Javascript
JS实现单行文字不间断向上滚动的方法
Jan 29 Javascript
轻松实现javascript数据双向绑定
Nov 11 Javascript
检查表单元素的值是否为空的实例代码
Jun 16 Javascript
微信小程序 地图(map)实例详解
Nov 16 Javascript
基于JavaScript实现数码时钟效果
Mar 30 Javascript
详解使用WebPack搭建React开发环境
Aug 06 Javascript
简述Vue中容易被忽视的知识点
Dec 09 Javascript
vue打开子组件弹窗都刷新功能的实现
Sep 21 Javascript
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从memcache读取数据再批量写入mysql的方法
2014/12/29 PHP
PHP 与 UTF-8 的最佳实践详细介绍
2017/01/04 PHP
PHP面向对象之里氏替换原则简单示例
2018/04/08 PHP
PHP使用标准库spl实现的观察者模式示例
2018/08/04 PHP
JavaScript 笔记二 Array和Date对象方法
2010/05/22 Javascript
AJAX异步从优酷专辑中采集所有视频及信息(JavaScript代码)
2010/11/20 Javascript
jquery的相对父元素和相对文档定位示例代码
2013/08/02 Javascript
javascript对下拉列表框(select)的操作实例讲解
2013/11/29 Javascript
JS控制输入框内字符串长度
2014/05/21 Javascript
AngularJS中的Directive自定义一个表格
2016/01/25 Javascript
jQuery实现的文字hover颜色渐变效果实例
2016/02/20 Javascript
SWFUpload多文件上传及文件个数限制的方法
2016/05/31 Javascript
JQuery异步加载PartialView的方法
2016/06/07 Javascript
关于网页中的无缝滚动的js代码
2016/06/09 Javascript
vue router下的html5 history在iis服务器上的设置方法
2017/10/18 Javascript
使用layui定义一个模块并使用的例子
2019/09/14 Javascript
解决vue刷新页面以后丢失store的数据问题
2020/08/11 Javascript
vue axios封装httpjs,接口公用配置拦截操作
2020/08/11 Javascript
python实现RSA加密(解密)算法
2016/02/17 Python
详解python之简单主机批量管理工具
2017/01/27 Python
Python yield 使用方法浅析
2017/05/20 Python
Python爬虫包BeautifulSoup异常处理(二)
2018/06/17 Python
使用EduBlock轻松学习Python编程
2018/10/08 Python
Pyqt5 实现跳转界面并关闭当前界面的方法
2019/06/19 Python
python实现读取excel文件中所有sheet操作示例
2019/08/09 Python
pandas数据处理进阶详解
2019/10/11 Python
Python实现图片裁剪的两种方式(Pillow和OpenCV)
2019/10/30 Python
pytorch sampler对数据进行采样的实现
2019/12/31 Python
宝拉珍选美国官网:Paula’s Choice美国
2018/01/07 全球购物
学习雷锋标语
2014/06/25 职场文书
辩论会主持词
2015/07/03 职场文书
四则混合运算教学反思
2016/02/23 职场文书
MySQL Threads_running飙升与慢查询的相关问题解决
2021/05/08 MySQL
探讨Java中的深浅拷贝问题
2021/06/26 Java/Android
vue中利用mqtt服务端实现即时通讯的步骤记录
2021/07/01 Vue.js
python flappy bird小游戏分步实现流程
2022/02/15 Python