原生js无缝轮播插件使用详解


Posted in Javascript onMarch 09, 2020

这篇博文主要讲如何使用原生js来实现一个兼容 IE9+ 的无缝轮播图。主要知识点如下:

  • 面向对象
  • js优化之节流函数
  • js运动

效果

原生js无缝轮播插件使用详解

html结构

<div class="sliders-wraper" id="rotation-1">
 <ul class="sliders clear">
 <li class="slider" style="background:purple">5</li>
 <li class="slider" style="background:pink">1</li>
 <li class="slider" style="background:beige">2</li>
 <li class="slider" style="background:gold">3</li>
 <li class="slider" style="background:skyblue">4</li>
 <li class="slider" style="background:purple">5</li>
 <li class="slider" style="background:pink">1</li>
 </ul>
 <div class="pagenation">
 <div class="page page-active"><a></a></div>
 <div class="page"><a></a></div>
 <div class="page"><a></a></div>
 <div class="page"><a></a></div>
 <div class="page"><a></a></div>
 </div>
 <span class='prev rotation-btn'><</span>
 <span class='next rotation-btn'>></span>
</div>

css样式

*{margin: 0;padding: 0;box-sizing: border-box;}
.clear{zoom: 0;}
.clear:after{content: '';display: block;overflow: hidden;clear: both;widows: 0;height: 0;}
.sliders-wraper{width: 100%;height: 400px;line-height: 400px;
 overflow: hidden;position: relative;text-align: center;}
.sliders{position: absolute;list-style: none;font-size: 50px;}
.slider{float: left;}
.rotation-btn{position: absolute;top: 50%;width: 50px;height: 50px;
 line-height: 50px;margin-top: -25px;font-size: 30px;color: #ccc;cursor: pointer;}
.prev{left:0;}
.next{right:0;}
.pagenation{position: absolute;bottom: 10px;width: 100%;height: 25px;line-height: 25px;}
.pagenation .page{width: 40px;height: 25px;display: inline-block;cursor: pointer;}
.pagenation .page a{display: block;width: 30px;height: 5px;border: 1px solid #ccc;
 border-radius: 5px;background: transparent;margin: 10px auto;}
.pagenation .page-active a{border-color: #0076ff;background-color: #0076ff;}

js

;(function(doc, win){
 function Rotation(obj){
 this.wraper = doc.getElementById(obj.el) //窗口
 this.sliders = this.wraper.getElementsByClassName('sliders')[0] //图片父盒子
 this.slideList = this.sliders.getElementsByClassName('slider') //所有图片
 this.length = this.slideList.length
 this.index = 1 //当前显示的图片的索引
 this.timer = null //单张图片运动定时器
 this.animation = null //自动轮播定时器

 // 在obj中可以自定义的参数
 this.mode = 'easy-in-out'//动画曲线,可选 'linear'
 this.step = 5 //匀速运动滚动步长
 this.delay = 2500 //轮播间隔
 this.duration = 40 //单张图片动画时长
 this.auto = true //是否开启自动轮播
 this.btn = false //是否有左右按钮
 this.focusBtn = true //是否支持焦点事件

 for(var k in obj)
 this[k] = obj[k]
 if(this.btn){
 this.prev = this.wraper.getElementsByClassName('prev')[0]
 this.next = this.wraper.getElementsByClassName('next')[0]
 }
 if(this.focusBtn){
 this.pagenation = this.wraper.getElementsByClassName('pagenation')[0]
 this.pageList = this.pagenation.getElementsByClassName('page')
 this.activePage = 0 //当前的焦点的索引
 }
 this.init()
 }

 var D = Rotation.prototype
 /*
 * func init
 * 初始化函数
 * @para 0 
 */
 D.init = function(){
 this.width = this.wraper.clientWidth
 if(this.mode == 'linear')
 this.duration = 1
 for(var i=0; i<this.length; i++)
 this.slideList[i].style.width = this.width + 'px'

 this.sliders.style.width = this.width * this.length + 'px'
 this.sliders.style.marginLeft = -this.width + "px";
 this.handler()
 this.auto && this.autoPlay()
 }

 D.getStyle = function(obj, attr){
 return obj.currentStyle?obj.currentStyle[attr]:getComputedStyle(obj, false)[attr]; 
 }
 /*
 * @method bind
 * 事件绑定函数
 * bind events 
 */
 D.handler = function(){
 var _th = this,i=0
 if(this.btn){
 this.prev.onclick = function(){
 _th.turnLeft();
 }
 this.next.onclick = function(){
 _th.turnRight();
 }
 }
 if(this.focusBtn){
 for(; i<this.pageList.length; i++){
 this.pageList[i].key = i
 this.pageList[i].function(){
  _th.index = this.key + 1
  _th.toggleClass()
 }
 }
 }
 this.wraper.onmouseover = function(){
 clearInterval(_th.animation);
 }
 this.wraper.onmouseout = function(){
 _th.auto && _th.autoPlay()
 }
 }
 /*
 * func turnRight
 * 向右轮播函数
 * @para 0
 */
 D.turnRight = function(){
 this.index++;
 if(this.index == this.length-1){
 this.index=1;
 this.sliders.style.marginLeft = 0;
 }
 this.toggleClass(); 
 }
 /*
 * func turnLeft
 * 向左轮播函数
 * @para 0
 */
 D.turnLeft = function(){
 this.index--;
 if(this.index == 0){
 this.index = this.length-2;
 this.sliders.style.marginLeft = -this.width * (this.length-1) + "px";
 }
 this.toggleClass();
 }
 /*
 * func toggleClass
 * 改变数字焦点样式,轮播动画核心函数调用
 * @para 0
 */
 D.toggleClass = function(){
 if(this.focusBtn){
 this.pageList[this.activePage].className = "page";
 this.pageList[this.index-1].className = "page page-active";
 this.activePage = this.index-1;
 }
 this.slide(-this.index * this.width);
 }
 /*
 * func slide
 * 图片滚动函数,核心函数
 * @param ins 滚动终点
 */
 D.slide = function(ins){
 var _th = this
 // 防止动画过度过程中计算错误
 if(_th.timer) clearInterval(_th.timer);

 _th.timer = setInterval(move,_th.duration);

 function move(){

 var currentPosition = parseFloat(_th.sliders.style.marginLeft);
 // 根据起始点和目标位置的比较确定向哪个方向移动
 var n = ins-currentPosition<0?-1:1;

 if(Math.abs(ins-currentPosition) < _th.step){
 _th.sliders.style.marginLeft = ins + "px";
 clearInterval(_th.timer);
 }else{
 // 变速运动关键,注释变为匀速运动
 if(_th.mode == 'easy-in-out')
  _th.step = Math.abs(ins-currentPosition)/5
 _th.sliders.style.marginLeft = currentPosition + n*_th.step + "px";
 }
 
 }
 }
 /*
 * func autoPlay
 * 自动轮播函数
 * @para 0
 */
 D.autoPlay = function(){
 var _th = this
 clearInterval(_th.animation)
 _th.animation = setInterval(function(){
 _th.turnRight();
 },_th.delay)
 }
 /*
 * func debounce
 * 节流函数
 * @para fn<要执行的函数> delay<节流时间>
 * @value func
 */
 D.debounce = function(fn,delay){
 var timer = null
 return function(){
 if(timer){
 clearTimeout(timer)
 }
 timer = setTimeout(fn,delay)
 }
 }
 /*
 * func refresh
 * 自动刷新函数,这里采用节流是防止刷新操作太过于频繁导致性能下降
 * @para 0
 */
 D.refresh = function(){
 var _th = this
 this.debounce(function(){
 _th.init()
 _th.toggleClass()
 },100)()
 }
 /*
 * func rotation
 * 实例化函数
 * @para obj 实例化的具体参数
 * @value 返回具体实例
 */
 win.rotation = function(obj){
 return new Rotation(obj)
 }
})(document, window)

调用方式

var r2 = rotation({
 el: 'rotation-1',
 mode: 'easy-in-out', //运动曲线
 auto: true,//开启自动轮播
 btn: true, //左右按钮
 focusBtn: false//焦点
})
window.onresize = function(){
 r2 && r2.refresh()
}

精彩专题分享:jQuery图片轮播 JavaScript图片轮播 Bootstrap图片轮播

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
调试Javascript代码(浏览器F12及VS中debugger关键字)
Jan 25 Javascript
JS控制一个DIV层在指定时间内消失的方法
Feb 17 Javascript
js实现文本框选中的方法
May 26 Javascript
JS组件中bootstrap multiselect两大组件较量
Jan 26 Javascript
理解javascript异步编程
Jan 27 Javascript
JavaScript获取当前运行脚本文件所在目录的方法
Feb 03 Javascript
js中小数向上取整数,向下取整数,四舍五入取整数的实现(必看篇)
Feb 13 Javascript
JavaScript实现简单的星星评分效果
May 18 Javascript
dropload.js插件下拉刷新和上拉加载使用详解
Oct 20 Javascript
深入理解vue中slot与slot-scope的具体使用
Jan 26 Javascript
区别JavaScript函数声明与变量声明
Sep 12 Javascript
浅析vue中的nextTick
Dec 28 Vue.js
微信小程序自定义弹出模态框禁止底部滚动功能
Mar 09 #Javascript
JavaScript享元模式原理与用法实例详解
Mar 09 #Javascript
JavaScript装饰者模式原理与用法实例详解
Mar 09 #Javascript
JavaScript适配器模式原理与用法实例详解
Mar 09 #Javascript
JavaScript中的this基本问题实例小结
Mar 09 #Javascript
Nuxt页面级缓存的实现
Mar 09 #Javascript
JavaScript设计模式之门面模式原理与实现方法分析
Mar 09 #Javascript
You might like
thinkphp 多表 事务详解
2013/06/17 PHP
跟我学Laravel之路由
2014/10/15 PHP
在PHP语言中使用JSON和将json还原成数组的方法
2016/07/19 PHP
CL vs ForZe BO5 第一场 2.13
2021/03/10 DOTA
深入理解JavaScript作用域和作用域链
2011/10/21 Javascript
深入理解JavaScript系列(43):设计模式之状态模式详解
2015/03/04 Javascript
学习javascript的闭包,原型,和匿名函数之旅
2015/10/18 Javascript
JavaScript中字符串与Unicode编码互相转换的实现方法
2015/12/18 Javascript
jQuery animate easing使用方法图文详解
2016/06/17 Javascript
jQuery实现6位数字密码输入框
2016/12/29 Javascript
js通过keyCode值判断单击键盘上某个键,然后触发指定的事件方法
2017/02/19 Javascript
Bootstrap 设置datetimepicker在屏幕上面弹出设置方法
2017/03/21 Javascript
AngularJS中使用ngModal模态框实例
2017/05/27 Javascript
angularJS自定义directive之带参方法传递详解
2018/10/09 Javascript
JS函数节流和防抖之间的区分和实现详解
2019/01/11 Javascript
jQuery pager.js 插件动态分页功能实例分析
2019/08/02 jQuery
layui数据表格跨行自动合并的例子
2019/09/02 Javascript
JS获取当前时间戳方法解析
2020/08/29 Javascript
[03:15]2014DOTA2国际邀请赛 专访国士无双信心满满
2014/07/12 DOTA
python中urllib模块用法实例详解
2014/11/19 Python
Python中字符编码简介、方法及使用建议
2015/01/08 Python
python数据结构链表之单向链表(实例讲解)
2017/07/25 Python
python的格式化输出(format,%)实例详解
2018/06/01 Python
使用python制作一个为hex文件增加版本号的脚本实例
2019/06/12 Python
python使用pygame实现笑脸乒乓球弹珠球游戏
2019/11/25 Python
Python 如何调试程序崩溃错误
2020/08/03 Python
个人简历自我评价
2014/02/02 职场文书
电视节目策划方案
2014/05/16 职场文书
幼儿园爱国卫生月活动总结
2014/06/30 职场文书
2015年幼儿园后勤工作总结
2015/04/25 职场文书
网络营销实训总结
2015/08/03 职场文书
个人职业生涯规划之自我评估篇
2019/09/03 职场文书
vue组件的路由高亮问题解决方法
2021/05/11 Vue.js
python如何利用traceback获取详细的异常信息
2021/06/05 Python
试了下Golang实现try catch的方法
2021/07/01 Golang
《帝国时代4》赛季预告 新增内容编译器可创造地图
2022/04/03 其他游戏