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入门知识简介
Mar 04 Javascript
初识javascript 文档碎片
Jul 13 Javascript
基于Unit PNG Fix.js有时候在ie6下不正常的解决办法
Jun 26 Javascript
jQuery实现菜单感应鼠标滑动动画效果的方法
Feb 28 Javascript
使用window.prompt()实现弹出用户输入的对话框
Apr 13 Javascript
jQuery实现打开页面渐现效果示例
Jul 27 Javascript
JS实现的二叉树算法完整实例
Apr 06 Javascript
BootStrap Table 后台数据绑定、特殊列处理、排序功能
May 27 Javascript
JavaScript30 一个月纯 JS 挑战中文指南(英文全集)
Jul 23 Javascript
Node.js成为Web应用开发最佳选择的原因
Feb 05 Javascript
vue favicon设置以及动态修改favicon的方法
Dec 21 Javascript
JS造成内存泄漏的几种情况实例分析
Mar 02 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与SQL注入攻击[一]
2007/04/17 PHP
实用函数9
2007/11/08 PHP
PHP中new static()与new self()的区别异同分析
2014/08/22 PHP
PHP中使用正则表达式提取中文实现笔记
2015/01/20 PHP
基于PHP+jQuery+MySql实现红蓝(顶踩)投票代码
2015/08/25 PHP
PHP实现基于mysqli的Model基类完整实例
2016/04/08 PHP
详解Yii2高级版引入bootstrap.js的一个办法
2017/03/21 PHP
Laravel模糊查询区分大小写的实例
2019/09/29 PHP
js实现右下角提示框的方法
2015/02/03 Javascript
js实现上一页下一页的效果【附代码】
2016/03/10 Javascript
Bootstrap3制作图片轮播效果
2016/05/12 Javascript
Angular2 环境配置详细介绍
2016/09/21 Javascript
js编写的treeview使用方法
2016/11/11 Javascript
JQuery validate 验证一个单独的表单元素实例
2017/02/17 Javascript
详解vue项目构建与实战
2017/06/27 Javascript
详解Chai.js断言库API中文文档
2018/01/31 Javascript
基于Axios 常用的请求方法别名(详解)
2018/03/13 Javascript
小程序云开发初探(小结)
2018/10/24 Javascript
vue路由--网站导航功能详解
2019/03/29 Javascript
JS实现的对象去重功能示例
2019/06/04 Javascript
Vue组件通信中非父子组件传值知识点总结
2019/12/05 Javascript
Vue+ElementUI table实现表格分页
2019/12/14 Javascript
用js实现放大镜效果
2020/10/28 Javascript
使用Python搭建虚拟环境的配置方法
2018/02/28 Python
Django项目中用JS实现加载子页面并传值的方法
2018/05/28 Python
对python读取CT医学图像的实例详解
2019/01/24 Python
python实现自动化上线脚本的示例
2019/07/01 Python
python 中xpath爬虫实例详解
2019/08/26 Python
如何用border-image实现文字气泡边框的示例代码
2020/01/21 HTML / CSS
DERMAdoctor官网:美国著名皮肤护理品牌
2019/07/06 全球购物
机械电子工程专业自荐书
2014/06/10 职场文书
2014年商场国庆节活动策划方案
2014/09/16 职场文书
大学生思想道德自我评价
2015/03/09 职场文书
党小组推荐意见
2015/06/02 职场文书
大学生党课心得体会
2016/01/07 职场文书
导游词之沈阳清昭陵
2019/12/28 职场文书