<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>circular1</title> <style> .container { width: 522px; height: 222px; box-sizing: border-box; padding: 10px; border: 1px solid gray; position: relative; margin: auto; top: 30px; overflow: hidden; } ul, ol { list-style: none; padding: 0px; margin: 0px; } ul li { float: left; } .box { width: 500px; height: 200px; position: relative; overflow: hidden; } .pics { width: 1000%; position: absolute; left: -500px; } .box img { width: 500px; height: 200px; } .container ol { position: absolute; bottom: 20px; text-align: center; width: 500px; } .container ol li { display: inline-block; width: 20px; height: 20px; border-radius: 50%; background-color: white; color: #333; line-height: 20px; text-align: center; margin-right: 10px; cursor: pointer; user-select: none; } .container ol li:last-child { margin-right: 0; } .container ol li.cur { background: purple; color: white; } .container .left, .container .right { position: absolute; width: 40px; height: 60px; line-height: 60px; text-align: center; color: white; background-color: rgba(0, 0, 0, .3); cursor: pointer; top: 100px; margin-top: -30px; display: none; user-select: none; } .container:hover .left, .container:hover .right { display: block; } .container .left { left: 10px; } .container .right { right: 10px; } </style> </head> <body> <div class="container"> <div class="box"> <ul class="pics"> <li><img src="../images/1.jpg"></li> <li><img src="../images/2.jpg"></li> <li><img src="../images/3.jpg"></li> <li><img src="../images/4.jpg"></li> <li><img src="../images/5.jpg"></li> </ul> </div> <div class="left"><</div> <div class="right">></div> </div> <script> //动画函数 function animate(obj, target){ clearInterval(obj.timer); let frameTime = Math.abs((target - obj.offsetLeft) / 62); let speed = target < obj.offsetLeft ? -frameTime : frameTime; obj.timer = setInterval( () => { let leftDistance = Math.abs(target - obj.offsetLeft); if( leftDistance < Math.abs(speed) ){ obj.style.left = target + 'px'; }else{ obj.style.left = obj.offsetLeft + speed + 'px'; } }, 16); } //获取相关元素,在前后添加图片,生成小点 let container = document.getElementsByClassName('container')[0]; let pics = document.getElementsByClassName('pics')[0]; let picWidth = pics.children[0].offsetWidth; let left = document.getElementsByClassName('left')[0]; let right = document.getElementsByClassName('right')[0]; pics.appendChild(pics.children[0].cloneNode(true)); pics.insertBefore(pics.children[pics.children.length-2].cloneNode(true),pics.children[0]); let ol = document.createElement('ol'); for( let i = 0, len = pics.children.length-2; i < len; i++){ let li = document.createElement('li'); li.innerHTML = i + 1; ol.appendChild(li); } container.appendChild(ol); //控制变量 let timer = null; let curImg = 1; let dot = 0; //改变小点样式 function dotStyle(){ for(let i = 0, len = ol.children.length; i< len; i++){ if( dot === i){ ol.children[i].className = 'cur'; }else { ol.children[i].className = ''; } } } //点击小点 for(let i = 0, len = ol.children.length; i < len; i++){ ol.children[i].index = i; ol.children[i].addEventListener('click',function(){ //修正位置 if(curImg === pics.children.length - 1){ pics.style.left = pics.offsetLeft + picWidth * (pics.children.length - 2) + 'px'; } if(curImg === 0){ pics.style.left = pics.offsetLeft - picWidth * (pics.children.length - 2) + 'px'; } dot = this.index; curImg = this.index + 1; dotStyle(); animate(pics,- picWidth * curImg); }); } //索引限定 function range(index, step, min, max){ index += step; if( index > max){ index = index - max - 1 + min; } if( index < min){ index = max - (min - index - 1); } return index; } //修正 function amend(obj){ if(curImg === obj.children.length - 1){ curImg = 1; } if(curImg === 0){ curImg = obj.children.length - 2; } obj.style.left = - curImg * picWidth + 'px'; } //自动播放 function auto(){ clearInterval(timer); timer = setInterval( () => { if(curImg === pics.children.length - 1){ amend(pics); } curImg = range(curImg, 1, 0, pics.children.length - 1); dot = range(dot, 1, 0, ol.children.length - 1); dotStyle(); animate(pics, - picWidth * curImg); },2000) } //鼠标悬浮图片区 container.addEventListener('mouseenter',function(){ clearInterval(timer); }) container.addEventListener('mouseleave',function(){ auto(); }) //是否正在进行动画 function isAnimate(obj){ if(obj.offsetLeft % picWidth){ return true; }else{ return false; } } //向左或者向右 //参数:'left' 'right' function LOR(direction){ if(isAnimate(pics)){ return; } let step = null; if('left' === direction){ step = -1; }else{ step = 1; } if( 0 === curImg || pics.children.length - 1 === curImg){ amend(pics); } curImg = range(curImg, step, 0, pics.children.length - 1); dot = range(dot, step, 0, ol.children.length - 1) dotStyle(); animate(pics, - curImg * picWidth); } //点击向左 left.addEventListener('click', function(){ LOR('left'); }) //点击向右 right.addEventListener('click', function(){ LOR('right'); }) //初始化 curImg = 1; dot = 0; dotStyle(); animate(pics,- picWidth * curImg); auto(); </script> </body> </html>
嗯,更新一下。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>circular8</title> <style> .container { width: 522px; height: 222px; box-sizing: border-box; padding: 10px; border: 1px solid gray; margin: auto; position: relative; top: 30px; overflow: hidden; } ul, ol { list-style: none; padding: 0; margin: 0; } ul li { float: left; } .box { width: 500px; height: 200px; overflow: hidden; position: relative; } .pics { width: 1000%; position: absolute; left: -500px; } .box img { width: 500px; height: 200px; vertical-align: top; } .container ol { width: 500px; text-align: center; position: absolute; bottom: 20px; } .container ol li { width: 20px; height: 20px; line-height: 20px; display: inline-block; border-radius: 50%; background-color: #fff; color: #333; text-align: center; margin-right: 10px; cursor: pointer; user-select: none; } .container ol li:last-child { margin-right: 0; } .container ol li.cur { background-color: purple; color: #fff; } .container .left, .container .right { position: absolute; width: 40px; height: 60px; text-align: center; line-height: 60px; top: 111px; margin-top: -30px; background-color: rgba(0, 0, 0, .4); color: white; cursor: pointer; display: none; user-select: none; } .container:hover .left, .container:hover .right { display: block; } .container .left { left: 10px; } .container .right { right: 10px; } </style> </head> <body> <div class="container"> <div class="box"> <ul class="pics"> <li><img src="../images/1.jpg"></li> <li><img src="../images/2.jpg"></li> <li><img src="../images/3.jpg"></li> <li><img src="../images/4.jpg"></li> <li><img src="../images/5.jpg"></li> </ul> </div> </div> <script> let circular = { //各种变量 container: null, pics: null, picsLen: null, ol: null, olLen: null, picWidth: null, left: null, right: null, timer: null, dot: 0, curImg: 1, //初始化 init: function(container, pics){ this.container = container; this.pics = pics; this.picWidth = this.pics.children[0].offsetWidth; this.pics.appendChild(this.pics.children[0].cloneNode(true)); this.pics.insertBefore(this.pics.children[this.pics.children.length - 2].cloneNode(true), pics.children[0]); this.picsLen = this.pics.children.length; //生成小点 this.ol = document.createElement('ol'); for( let i = 0, len = this.picsLen - 2; i < len; i++){ let li = document.createElement('li'); li.innerHTML = i + 1; this.ol.appendChild(li); } this.container.appendChild(this.ol); this.olLen = this.ol.children.length; //定义 self 用于事件回调函数 let self = this; //小点注册点击事件 for( let i = 0; i < this.olLen; i++){ this.ol.children[i].index = i; this.ol.children[i].addEventListener('click', function(){ //修正位置 let distance = self.picWidth * (self.picsLen - 2); if( self.picsLen - 1 === self.curImg){ self.pics.style.left = self.pics.offsetLeft + distance + 'px'; } if( 0 === self.curImg){ self.pics.style.left = self.pics.offsetLeft - distance + 'px'; } self.dot = this.index; self.curImg = this.index + 1; self.dotStyle(); self.animate(self.pics, - self.picWidth * self.curImg); }); } //生成左右按键 this.left = document.createElement('div'); this.left.className = 'left'; this.left.innerHTML = '<'; this.right = document.createElement('div'); this.right.className = 'right'; this.right.innerHTML = '>'; this.container.appendChild(this.left); this.container.appendChild(this.right) //左右按键注册事件 this.left.addEventListener('click', function(){ self.LOR('left'); }); this.right.addEventListener('click', function(){ self.LOR('right'); }); //鼠标悬停图片区 this.container.addEventListener('mouseenter',function(){ clearInterval(self.timer); }); this.container.addEventListener('mouseleave',function(){ self.auto(); }); //开始运行 this.dot = 0; this.curImg = 1; this.dotStyle(); this.animate(this.pics, - this.picWidth * this.curImg); this.auto(); }, //动画函数 animate: function(obj, target){ clearInterval(obj.timer); let step = Math.abs(target - obj.offsetLeft) / 62; let speed = target < obj.offsetLeft ? -step : step; obj.timer = setInterval(() => { let leftDistance = Math.abs(target - obj.offsetLeft); if(leftDistance < Math.abs(speed)){ obj.style.left = target + 'px'; }else{ obj.style.left = obj.offsetLeft + speed + 'px'; } }, 16); }, //改变小点样式 dotStyle: function(){ for( let i = 0; i< this.olLen; i++){ if(this.dot === i){ this.ol.children[i].className = 'cur'; }else{ this.ol.children[i].className = ''; } } }, //索引限定 range: function(index, step, min, max){ index += step; index = index > max ? index - max - 1 + min : index; index = index < min ? max - (min - index - 1) : index; return index; }, //修正 amend: function(obj){ this.curImg = this.curImg === obj.children.length - 1 ? 1 : this.curImg; this.curImg = this.curImg === 0 ? obj.children.length - 2 : this.curImg; this.pics.style.left = - this.picWidth * this.curImg + 'px'; }, //图片运动 oneStep: function(step){ this.curImg = this.range(this.curImg, step, 0, this.picsLen - 1); this.dot = this.range(this.dot, step, 0, this.olLen - 1); this.dotStyle(); this.animate(this.pics, - this.picWidth * this.curImg); }, //自动播放 auto: function(){ clearInterval(this.timer); this.timer = setInterval(() => { if(this.picsLen - 1 === this.curImg){ this.amend(this.pics); } this.oneStep(1); }, 2000); }, //是否正在进行动画 isAnimate: function(obj){ if(obj.offsetLeft % this.picWidth){ return true; }else{ return false; } }, //向左或者向右 //参数: 'left','right' LOR: function(direction){ if(this.isAnimate(this.pics)){ return; } let step = 'left' === direction ? -1 : 1; if( 0 === this.curImg || this.picsLen - 1 === this.curImg){ this.amend(this.pics); } this.oneStep(step); } }; circular.init(document.getElementsByClassName('container')[0], document.getElementsByClassName('pics')[0]); </script> </body> </html>
文章最初发布在简书,时间为 2018.07.23 21:40 。