简易轮播图和无缝轮播图的实现
在这里我们运用面向对象的方法来书写编程:
简易轮播图
首先
// OOA:分析:
// 轮播图:点击左右按钮切换图片
// 1.选择元素
// 2.绑定点击事件
// 3.计算索引
// 4.根据索引,显示图片
// OOD:设计
// function Banner(){
// // 1.选择元素
// // 2.绑定点击事件
// this.init()
// }
// Banner.prototype.init = function(){
// // 绑定事件...
// // 3.计算索引
// this.changeIndex()
// }
// Banner.prototype.changeIndex = function(){
// // 计算索引
// // 4.根据索引,显示图片
// this.display()
// }
// Banner.prototype.display = function(){
// // 显示图片
// }
<!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>Document</title> <style> .banner{width:1000px;height:300px;margin: 20px auto;position: relative;overflow: hidden;} /* .imgbox{} */ .imgbox img{width: 1000px;height:300px;position: absolute;left:0;top:0;overflow: hidden} .imgbox img:nth-child(1){z-index: 1} /* .imgbox a img{width: 1000px;height: 300px} */ .btns input{position: absolute;top:130px;width:40px;height:40px;border: none;background: rgba(200,200,200,0.5);z-index: 9999999;} #left{left:0} #right{right:0} </style> </head> <body> <div class="banner"> <div class="imgbox"> <img src="img/1.jpg" alt=""> <img src="img/2.jpg" alt=""> <img src="img/3.jpg" alt=""> <img src="img/4.jpg" alt=""> <img src="img/5.jpg" alt=""> </div> <div class="btns"> <input type="button" id="left" value="<<<"> <input type="button" id="right" value=">>>"> </div> </div> </body> <script src="../move.js"></script> <script> function Banner(){ // 1.选择元素 this.imgs = document.querySelector(".imgbox").children; this.left = document.querySelector("#left"); this.right = document.querySelector("#right"); // 自定义的默认显示的图片:索引 this.index = 0; // 为了显示图片设置的层级 this.i = 2; // 2.绑定点击事件 this.init() } Banner.prototype.init = function(){ var that = this; // 绑定事件... this.right.onclick = function(){ // 3.计算索引 that.changeIndex(); } } Banner.prototype.changeIndex = function(){ // 计算索引 if(this.index === this.imgs.length-1){ this.index = 0; }else{ this.index++; } // 4.根据索引,显示图片 this.display() } Banner.prototype.display = function(){ // 显示图片 this.imgs[this.index].style.zIndex = this.i++; // this.imgs[this.index].style.width = 0; // move(this.imgs[this.index],{ // width:1000 // }) this.imgs[this.index].style.width = 0; this.imgs[this.index].style.height = 0; move(this.imgs[this.index],{ width:1000, height:300 }) // this.imgs[this.index].style.left = "-1000px"; // move(this.imgs[this.index],{ // left:0, // }) // this.imgs[this.index].style.width = "0"; // this.imgs[this.index].style.height = "0"; // move(this.imgs[this.index],{ // width:1000, // height:150 // },function(){ // move(this.imgs[this.index],{height:300}) // }.bind(this)) } new Banner(); </script> </html>
在这里我们提前封装了“move”JS文件,来实现轮播图的运动(如下):
function move(ele,json,callback){ clearInterval(ele.t); ele.t = setInterval(() => { var onoff = true; for(var i in json){ var iNow = parseInt(getStyle(ele,i)); var speed = (json[i] - iNow)/6; speed = speed<0 ? Math.floor(speed) : Math.ceil(speed); if(iNow != json[i]){ onoff = false; } ele.style[i] = iNow + speed + "px"; } if(onoff){ clearInterval(ele.t); callback && callback(); } }, 30); } function getStyle(ele,attr){ if(ele.currentStyle){ return ele.currentStyle[attr]; }else{ return getComputedStyle(ele,false)[attr]; } }
接着我们再实现无缝轮播图:
方法一:(这个方法运用的是将轮播图假设成一个像跑马灯一样的性质,不断的衔接的那种方式来实现轮播图效果;这个方法虽然实现了轮播图的效果,但是还是有一个小缺点,那就是当如果在轮播图的下方实现点击按钮到达对应图片的功能的时候,比如在图片1,你点击第5个按钮的话,虽然会跳转,但是中间的二三四图片也会相对的一闪而过,就会影响用户体验)
<!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>Document</title> <style> .banner{width:1000px;height:300px;margin: 20px auto;position: relative;} .imgbox{position: absolute;left:0;} .imgbox img{width: 1000px;height:300px;float:left;} .btns input{position: absolute;top:130px;width:40px;height:40px;border: none;background: rgba(200,200,200,0.5);} #left{left:0} #right{right:0} </style> </head> <body> <div class="banner"> <div class="imgbox"> <img src="img/1.jpg" alt=""> <img src="img/2.jpg" alt=""> <img src="img/3.jpg" alt=""> <img src="img/4.jpg" alt=""> <img src="img/5.jpg" alt=""> <!-- W1.复制第一张图片在最后,做过渡用 --> <img src="img/1.jpg" alt=""> </div> <div class="btns"> <input type="button" id="left" value="<<<"> <input type="button" id="right" value=">>>"> </div> </div> </body> <script src="../move.js"></script> <script> // OOA: // OOD: // OOP: function Banner(){ this.left = document.getElementById("left") this.right = document.getElementById("right") this.imgbox = document.querySelector(".imgbox") this.img = this.imgbox.children; this.imgbox.style.width = this.img.length * this.img[0].offsetWidth + "px"; this.index = 0; this.init() } Banner.prototype.init = function(){ var that = this; // this.left.onclick = function(){} this.right.onclick = function(){ that.changeIndex() } } Banner.prototype.changeIndex = function(){ if(this.index == this.img.length-1){ // W2.当索引到最后一个时,回到真正的第二张图片,索引为1 this.index = 1; // W3.索引设置好之后,将imgbox的left设置成初始值left:0 // move会从left:0走到-index1*width1000 this.imgbox.style.left = 0; }else{ this.index++ } this.display(); } Banner.prototype.display = function(){ move(this.imgbox,{ left:-this.index * this.img[0].offsetWidth }) } new Banner(); </script> </html>
所以为了解决上面遇到的那个瑕疵,我们就可以使用方法二:(在这个无缝轮播图中就完美的实现了无缝轮播,我们使用的原理是,就比如将图片都放置在将要显示的可视区域的左右,当我们需要哪一张出来的时候,就将它抽出来,就不会出现方法一那样的BUG,在方法二中,要注意左右按钮分别的控制,比当我点击左边按钮,那么要进来的假设是第三张图片,那么被抽离的当前图片就应该是第四张图片;而当我点击右键的按钮,假设要进来的是第二张图片,那么要被抽离的图片就是图便一)
<!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>Document</title> <style> .banner{width:1000px;height:300px;margin: 20px auto;position: relative;overflow: hidden;} .imgbox img{width: 1000px;height:300px;position: absolute;left:1000px;top:0;} .imgbox img:nth-child(1){left:0;} .btns input{position: absolute;top:130px;width:40px;height:40px;border: none;background: rgba(200,200,200,0.5);} #left{left:0} #right{right:0} </style> </head> <body> <div class="banner"> <div class="imgbox"> <img src="img/1.jpg" alt=""> <img src="img/2.jpg" alt=""> <img src="img/3.jpg" alt=""> <img src="img/4.jpg" alt=""> <img src="img/5.jpg" alt=""> </div> <div class="btns"> <input type="button" id="left" value="<<<"> <input type="button" id="right" value=">>>"> </div> </div> </body> <script src="../move.js"></script> <script> function Banner(){ this.left = document.getElementById("left") this.right = document.getElementById("right") this.imgbox = document.querySelector(".imgbox") this.img = this.imgbox.children; this.index = 0; // W1.设置要走的索引 this.iPrev = this.img.length - 1; this.init() } Banner.prototype.init = function(){ var that = this; // this.left.onclick = function(){} this.right.onclick = function(){ that.changeIndex() } } Banner.prototype.changeIndex = function(){ if(this.index == this.img.length-1){ this.index = 0; // W2.当要进来的是第0张时,走的是最后一张 this.iPrev = this.img.length-1 }else{ this.index++; // W3.正常情况下,走的都是进来的上一张,上一张为当前-1 this.iPrev = this.index-1; } this.display(); } Banner.prototype.display = function(){ // W4.根据要走的和要进来的索引 // 先设置初始位置,然后再开始走(move) // 要走的:this.img[this.iPrev] this.img[this.iPrev].style.left = 0; move(this.img[this.iPrev],{left:-this.img[0].offsetWidth}) // 要进来的:this.img[this.index] this.img[this.index].style.left = this.img[0].offsetWidth + "px"; move(this.img[this.index],{left:0}) } new Banner(); </script> </html>
方然在这几种轮播图的方法中,要十分清楚的计算出来,你当前这个图片所在的索引以及应该增加或扣除的长度。以及在move的玩法,有许多中,可以有各种的图片加载的方式,还是十分有趣的。