怎么实现无缝轮播图?用原生js写一遍

用原生js实现无缝轮播图
实现效果:

index.js:

var config = {
	imgWidth:380,//图片尺寸
	dotWidth:8,//小圆点尺寸
	doms:{
		divImgs:document.querySelector('.imgs'),
		divDots:document.querySelector('.circle'),
		divDirection:document.querySelector('.direction'),
		divContainer:document.querySelector('.container')
	},
	curIndex:0,//实际图片索引,0 ~ imgNumber-1
	timer:{
		duration:16,//运动间隔时间
		total:1000,//总时间
		id:null//计时器编号
	}
}
//图片的数量
config.imgNumber = config.doms.divImgs.children.length;
//初始化元素尺寸
config.imgsWidth = (config.imgNumber + 2)*config.imgWidth;
config.dotsWidth = (config.imgNumber + 2)*config.dotWidth;

//初始化
function inti(){
	intiWidth();
	intiCount();
	intiElement();
	intiPosition();
	function intiWidth(){
		config.doms.divImgs.style.width = config.imgsWidth + 'px';
        config.doms.divDots.style.width = config.dotsWidth + 'px';
	}
	function intiCount(){
		for(var i = 0; i < config.imgNumber; i ++){
			var p = document.createElement('p');
			config.doms.divDots.appendChild(p);
		}
	}
	function intiElement(){
	     var first = config.doms.divImgs.children[0],last = config.doms.divImgs.children[config.imgNumber-1];
	     var newImg = first.cloneNode(true);//深度克隆
	     config.doms.divImgs.appendChild(newImg);
	     newImg = last.cloneNode(true);
	     config.doms.divImgs.insertBefore(newImg,first);
	}
	function intiPosition(){
		var left = (-config.curIndex-1)*config.imgWidth;
        config.doms.divImgs.style.marginLeft  = left + 'px';
        setDots();//小圆点的激活状态位置设置
	}
}
inti();

//小圆点的激活状态位置设置
function setDots(){
	for(var i = 0; i < config.doms.divDots.children.length; i++){
    	var dot = config.doms.divDots.children[i];
    	if(i === config.curIndex){
    		dot.className = 'select';
    	}else{
    		dot.className = '';
    	}
    }
}

/*
  图片切换
  index: 图片索引
  directions: 图片切换方向(left,right)
*/
function switchTo(index,directions){
	if(index === config.curIndex){
		return;
	}
	if(!directions){
		directions = 'right';//默认状态下向右切换图片
	}

	//最终的显示图片; 图片容器的marginLeft
	var newLeft = (-index-1)*config.imgWidth;
	animateSwitch();
	//config.doms.divImgs.style.marginLeft  = newLeft + 'px';
    
    //小圆点的激活状态位置设置
    config.curIndex = index;
    setDots();

    //一张图片的总运动次数
    var number = Math.ceil(config.timer.total/config.timer.duration);
    //当前运动次数
    var curNumber = 0;
    
    var distance,//总运动距离
        totalWidth = config.imgNumber*config.imgWidth,
        marginLeft = parseFloat(getComputedStyle(config.doms.divImgs).marginLeft);
    if(directions === 'left'){
    	if(newLeft < marginLeft){
    		distance = newLeft - marginLeft;
    	}else{
    		distance = -(totalWidth-Math.abs(newLeft - marginLeft));
    	}
    }
    if(directions === 'right'){
    	if(newLeft > marginLeft){
    		distance = newLeft - marginLeft;
    	}else{
    		distance = totalWidth-Math.abs(newLeft - marginLeft);
    	}
    } 

    //每次改变的距离
    var everDistence = distance/number;   

    //逐步改变marginLeft
    function animateSwitch(){
    	clearAnimate();
    	config.timer.id = setInterval(function(){

    		marginLeft += everDistence;
    		if(directions === 'left' && Math.abs(marginLeft) > totalWidth){
    			marginLeft += totalWidth;
    		}
    		else if(directions === 'right' && Math.abs(marginLeft) < config.imgWidth){
    			marginLeft -= totalWidth;
    		}
    		config.doms.divImgs.style.marginLeft = marginLeft + 'px';

    		curNumber ++;
    		if(curNumber === number){
    			clearAnimate();
    		}
    	},config.timer.duration);
    }

    //清空计时器
    function clearAnimate(){
    	clearInterval(config.timer.id);
    	config.timer.id = null;
    }
}

//默认情况下自动向右轮播图片
var timer = setInterval(function(){
	toRight();
},2000);
config.doms.divContainer.onmouseleave = function() {
	timer = setInterval(function(){
	    toRight();
    },2000);
}
//鼠标移出则清空定时器
config.doms.divContainer.onmouseover = function() {
	clearInterval(timer);
}

//左右点击事件
config.doms.divDirection.onclick = function(e){
	clearInterval(timer);
	if(e.target.classList.contains('left')){
		toLeft();
	}
	if(e.target.classList.contains('right')){
		toRight();
	}
}

function toLeft(){
	var index = config.curIndex - 1;
	if(index < 0){
		index = config.imgNumber - 1;
	}
    switchTo(index,'right');
}
function toRight(){
	var index = config.curIndex + 1;
	if(index > config.imgNumber - 1){
		index = 0;
	}
	switchTo(index,'left');
}

//小圆点点击事件
config.doms.divDots.onclick = function(e){
	if(e.target.tagName === 'P'){
		var index = Array.from(this.children).indexOf(e.target);
		switchTo(index,index > config.curIndex? 'left' : 'right')
	}
}

index.html:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>无缝轮播图</title>
	<link rel="stylesheet" href="index.css">
</head>
<body>
	<div class="container">
		<div class="imgs">
			<img class="item" src="../imagejpg/1.jpg" alt="">
			<img class="item" src="../imagejpg/2.jpg" alt="">
			<img class="item" src="../imagejpg/3.jpg" alt="">
		</div>
		<div class="circle">
			<!-- <p></p>
			<p class="select"></p>
			<p></p>
			<p></p>
			<p></p> -->
		</div>
		<div class="direction">
			<div class="item left">&lt;</div>
			<div class="item right">&gt;</div>
		</div>
	</div>
	<script src="./index.js">
		
	</script>
</body>
</html>

index.css:

.container{
	width:380px;
	height:250px;
	border:1px solid;
	margin:0 auto;
	position:relative;
	overflow: hidden;
}
.container .imgs{
    
}
.container .imgs .item{
	width:380px;
	height:250px;
	display:block;
	float:left;
	top:0;
}
.container .circle{
	position:absolute;
	left:0;
	right:0;
	margin:0 auto;
	background:rgba(0,0,0,.3);
	bottom:8px;
	border-radius:5px;
}
.container .circle p{
	width:8px;
	height:8px;
	background:#fff;
	border-radius:50%;
	float:left;
	margin:2px;
	cursor:pointer;
}
.container .circle p.select{
	background:#f40;
}
.container .direction .item{
    background:rgba(0,0,0,.4);
	position:absolute;
    top:120px;
    width:20px;
    height:26px;
    padding:2px;
    box-sizing:border-box;
    display:none;
    cursor:pointer;
}
.container .direction .item:hover{
    background:rgba(0,0,0,.5);
}
.container:hover .direction .item{
    display:block;
}
.container .direction .left{
	left:0;
	border-radius:0 15px 15px 0;
}
.container .direction .right{
	right:0;
	padding-left:6px;
	border-radius:15px 0 0 15px;
}

你可能感兴趣的:(笔记)