轮播图之前也写了好几个,但是对于怎么实现无缝轮播还是有着不小的困惑,趁着周末了解了一下实现原理之后,重写了之前发布的案例(再看那个案例写的代码,真心心塞啊,不过只要努力学习,天天进步就好)。好了,下面就来说下如何实现无缝轮播。
百度了很多,各种各样的说法,但说的都不太明白,最后还是看了视频解决的。
我实现的这种思路是这样的:
1、假设你是用无序列表实现的哈,里面的每个li 包含着你的一个图片,首先呢,你得克隆一份第一张图片,并将其追加到你的ul 里面。
2、通过改变ul 的left 值,你实现了一张一张的向左轮播,但是到了倒数第二张的时候(倒数第一张已经是你克隆添加上去的了),已经是最后一张了对吧。
3、这个时候不要慌,你继续向左切换是不是显示的是最后一张呢(但是最后一张的内容是和第一张相同的),就在你要继续切换到下一张之前,你把ul 的left 值又设为 0 ,仔细想一想,本来显示的是倒数第一张,但是它长的和第一张一模一样(克隆的当然一样咯),此时你去改变ul 的left 值将ul 移到了最开始的位置(这里的改变必须通过css直接设置left值改变,这是关键,不能有过渡效果,不然怎么欺骗眼睛呢),但是那个位置上显示的和最后一克隆的一模一样,你的肉眼是分不清的吧。
4、然后你再点击,是不是切换到第二张了啊,妥妥的实现了无缝轮播对吧。
好了,再来看一下代码:
1 ; 2 (function($) { 3 // slidePic:为大图片的外层ul 4 // slideItem:底部小图片的外层ul 5 // preBtn,nextBtn分别为向前向后按钮 6 var slidePictures = function(slidePic,slideItem,preBtn,nextBtn) { 7 var self = this; 8 this.slidePic = $("#"+slidePic); //内容区域大图片的外层ul 9 this.slideItem = $("#"+slideItem); //底部小图片的外层ul 10 this.slidePic_li = $("#"+slidePic+" li"); //内容区域大图片 11 this.slideItem_li = $("#"+slideItem+" li"); //底部小图片 12 this.prevBtn = $("#"+preBtn); //前进按钮 13 this.nextBtn = $("#"+nextBtn); //后退按钮 14 this.length = this.slidePic_li.length; //ul中图片的个数,因为大图和小图是一一对应的,所以个数相同 15 this.speed = 500; //speed为图片滑动速度,数值越大速度越慢 16 this.index = 0; //第一次显示的是第一张图片,所以索引为0;表明当前正在显示的图片索引 17 this.timer;//定义一个定时器参数 18 // 初始化各项参数和属性 19 self.init(); 20 // 首先克隆一份第一张图片,并将其添加到外层ul中 21 var clone = this.slidePic_li.first().clone(); 22 this.slidePic.append(clone); 23 // 这里需要重新获取一下li,因为之前的this.slidePic_li保存的是克隆前的数据 24 this.length = $("#slide_pic li").length; 25 26 this.prevBtn.click(function() { 27 self.moveByClick(1); 28 }); 29 this.nextBtn.click(function() { 30 self.moveByClick(-1); 31 }); 32 } 33 slidePictures.prototype = { 34 // 初始化函数,当页面刚加载完给页面一些默认的样式,或者执行相关函数 35 init: function() { 36 // 首先给外层ul一个left属性为0; 37 this.slidePic.css("left", 0); 38 // 获取每一个图片的宽度 39 this.width = this.slidePic_li.width(); 40 // 将第一个小图片透明度默认设为1 41 this.slideItem_li.first().css("opacity", "1"); 42 // 给每一个小图片添加一个id属性,用于标识 43 this.giveItemAttrId(); 44 this.autoChange(); 45 this.cancleTimer(); 46 this.mouseoverShowBigPic(); 47 }, 48 // 突出显示底部小图片,用于标识当前大图位置,id为0即显示第一个 49 showItem: function(id) { 50 // 判断id值 51 var item = id; 52 if (item == this.length - 1) { 53 item = 0; 54 } 55 // 将所有的小图片透明度设为.3 56 this.slideItem_li.css("opacity", ".3"); 57 // 将当前id的小图片透明度设为1 58 this.slideItem_li.eq(item).css("opacity", "1"); 59 }, 60 // 得到当前透明度为needOpc的图片序号 61 getCurrentShowPic: function(needOpc) { 62 var item = 0; 63 this.slideItem_li.each(function(index, el) { 64 var opc = $(this).css("opacity"); 65 if (opc == needOpc) { 66 item = index; 67 } 68 }); 69 return item; 70 }, 71 mouseoverShowBigPic:function(){ 72 var self = this; 73 this.slideItem_li.on(\'mouseover\',function(){ 74 var id = $(this).attr("id"); 75 self.showNow(id);//显示大图片 76 self.showItem(id);//显示对应小图片 77 }) 78 }, 79 // 鼠标划过小图片时显示对应的大图 80 showNow: function(id) { 81 82 // 找到当前显示的图片的序号,item为当前序号 83 var item = this.getCurrentShowPic(); 84 // 计算需要移动的距离 85 var needMove = id * this.width; 86 // 如果当前显示的图片在鼠标划过的图片的左方,则向左滑动,否则向右滑动 87 if (id > item) { 88 this.slidePic.stop().animate({ left: "-" + needMove + "px" }, this.speed); 89 } else { 90 this.slidePic.stop().animate({ left: "-" + needMove + "px" }, this.speed); 91 } 92 // 更新this.index; 93 this.index = id; 94 }, 95 // 每次鼠标点击左右按钮时滑动一张图片 96 moveByClick: function(flag) { 97 //如果没有传入参数则默认为1; 98 var flag = flag||-1; 99 // flag用于标记点击的是左键还是右键,flag > 0为左键,反之为右键 100 // length为图片的个数 101 var length = this.length; 102 var width = this.width; 103 var speed = this.speed; 104 // 当点击的是左键时 105 if (flag > 0) { 106 this.index--; 107 if (this.index == -1) { 108 this.slidePic.css("left", "-" + (length - 1) * width + "px"); 109 // 突出显示对应的底部小图片 110 this.index = length - 2; 111 } 112 this.slidePic.stop().animate({ left: "-" + this.index * width + "px" }, speed); 113 this.showItem(this.index); 114 115 } else { //点击右键时 116 this.index++; 117 /*当index为最后一张图片时,先将外层ul的left值设为0 118 此时最后一张图片为后来克隆添加上的,将left值改为0后实际上显示的是第一张图片了 119 但是由于最后一张和第一张相同,人眼看不出差别,所以以为还没有改变 120 然后再将index设为1,让其切换到下一张图片,从而实现无缝轮播 121 点击左键时原理相同 122 */ 123 if (this.index == length) { 124 this.slidePic.css("left", "0px"); 125 this.index = 1; 126 } 127 this.slidePic.stop().animate({ left: "-" + this.index * width + "px" }, speed); 128 this.showItem(this.index); 129 130 } 131 }, 132 // 将所有的小图片透明度设为需要的值 133 hideAllitem: function(opc) { 134 this.slideItem_li.each(function(index, el) { 135 $(this).css("opacity", opc); 136 }); 137 }, 138 139 // 自动切换 140 autoChange: function() { 141 var self = this; 142 this.timer = setInterval(function(){ 143 self.moveByClick(); 144 },1500); 145 }, 146 //当鼠标划过相关区域时,停止自动播放 147 cancleTimer:function(){ 148 var self = this; 149 $(".jq_wrap").on("mouseover",function(){ 150 clearInterval(self.timer); 151 }); 152 $(".jq_wrap").on("mouseout",function(){ 153 self.autoChange(); 154 }) 155 }, 156 // 给底部小图片一个id属性,用于标识 157 giveItemAttrId: function() { 158 var self = this; 159 this.slideItem_li.each(function(index, el) { 160 $(this).attr("id", index); 161 }); 162 } 163 }; 164 window["slidePictures"] = slidePictures; 165 })(jQuery);