原生js无缝轮播插件详解面向对象

开始之前
这篇博文主要讲如何使用原生js来实现一个兼容 IE9+ 的无缝轮播图。主要知识点如下:
  • 面向对象
  • 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].onmouseover=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()
}

大功告成了,欢迎交流和留下宝贵意见!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,关于无缝轮播,可以通过原生JS手写实现。下面是一个简单的无缝无限轮播的carousel实现,你可以参考一下: HTML部分: ```html <div class="carousel"> <ul class="carousel-list"> <li><img src="img1.jpg"></li> <li><img src="img2.jpg"></li> <li><img src="img3.jpg"></li> <li><img src="img4.jpg"></li> </ul> </div> ``` CSS部分: ```css .carousel { position: relative; overflow: hidden; width: 600px; height: 400px; } .carousel-list { position: absolute; left: 0; top: 0; width: 10000px; height: 400px; margin: 0; padding: 0; list-style: none; } .carousel-list li { float: left; width: 600px; height: 400px; margin: 0; padding: 0; } ``` JS部分: ```javascript var carousel = document.querySelector('.carousel'); var carouselList = document.querySelector('.carousel-list'); var carouselItems = document.querySelectorAll('.carousel-list li'); var carouselWidth = carousel.offsetWidth; var currentIndex = 0; // 克隆第一张图片,并放到最后 var firstItem = carouselItems[0].cloneNode(true); carouselList.appendChild(firstItem); // 点击左右按钮的事件处理函数 function handleButtonClick(event) { var target = event.target; if (target.classList.contains('prev')) { currentIndex--; if (currentIndex < 0) { currentIndex = carouselItems.length - 1; carouselList.style.left = -currentIndex * carouselWidth + 'px'; } } else if (target.classList.contains('next')) { currentIndex++; if (currentIndex >= carouselItems.length) { currentIndex = 0; carouselList.style.left = 0; } } var left = -currentIndex * carouselWidth; carouselList.style.left = left + 'px'; } // 绑定左右按钮的事件 var prevBtn = document.createElement('button'); prevBtn.classList.add('prev'); prevBtn.innerText = '上一张'; prevBtn.addEventListener('click', handleButtonClick); var nextBtn = document.createElement('button'); nextBtn.classList.add('next'); nextBtn.innerText = '下一张'; nextBtn.addEventListener('click', handleButtonClick); carousel.appendChild(prevBtn); carousel.appendChild(nextBtn); ``` 这段代码实现了无限轮播,并且可以通过左右按钮控制图片的切换。你可以将这段代码复制到本地运行,看看效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值