一、前言 说起轮播图,种类那可是五花八门,什么淡入淡出呀、旋转木马呀、3D轮播呀、无缝轮播呀等等,简直是秀的头皮发麻~
本文要讲的就是其中的无缝轮播,小伙伴们知道是怎么实现的吗,如果不知道的话,嘿嘿,你就接着往下看吧。如果你知道的话,就当捧个场,也往下看吧~ html和css完成静态布局、js获取并且操纵元素,定时器的应用,节流函数,日期对象等等。 二、无缝轮播的原理首先,我们来看看什么是无缝轮播,就像下图所示:
其大概过程就是,上一张图片从左往右(或从右往左离开),下一张图片从左往右(或从右往左)进入。哎呀,貌似很简单的样子,有些小伙伴立马就想到了一个大容器里面有一个ul,ul里面有若干个li并且存放图片,把每个li的宽度设置成和容器同宽,然后每次点击的时候改变ul的left值就行了。嗯,很想很有道理的样子,于是三下五除二就做出来了,但是却发现有点问题,就像下面这样:
从第一张到倒数第二张图片还好,但是从最后一张图片到第一张图片就有问题了,并没有从最后一张图片直接切换到第一张图片,而是经过了中间的图片慢慢过渡到第一张图片(第一张图片到最后一张图片也同理),这显然不是预期的效果。问题既然已经发现了,就要去解决它,那么如何才能达到从最后一张图片直接切换到第一张图片(或第一张到最后一张),也就是无缝的效果,答案很简单,我们需要多一张图片(这张图片和第一张图片是相同的)放在图片列表的最后!为什么需要这样一张图片,请往下看。
我们在上面已经清楚要解决的就是首尾图片间的切换问题,所以在引入多一张图片之后,可以让轮播从倒数第二张图片(在没有引入图片之前的最后一张图片)切换到最后一张图片(新引入的图片)的动画完成之后,再瞬间跳转到第一张图片,请看下图(我把外面容器的overflow:hidden去掉了以便大家理解): - 把overflow:hidden加上,利用视觉差之后
嘿嘿,是不是很神奇,多引入了一张图片我们就把刚才的问题解决了,至于从第一张到最后一张图片的切换,把刚才的过程倒过来就行了。 三、无缝轮播演示- 这里我用到了节流函数,如果你还不知道什么是节流函数的话,可以点击下方链接去我另外一篇文章查看。
点我跳转Javascript函数式编程之节流函数 /* css代码 */body{ background-color: #333;}ul{ position: absolute; left: 0; list-style: none; padding: 0;}.wrap{ overflow: hidden; position: relative; width: 700px; height: 450px; margin: 100px auto 0;}.wrap .btn{ position: absolute; top: 50%; z-index: 1; width: 50px; height: 80px; margin-top: -40px; background-color: rgba(0,0,0,.5); color: #fff; text-align: center; line-height: 80px; cursor: pointer;}.wrap .left{ left: 0;}.wrap .right{ right: 0;}.img-list{ top: 0; margin: 0; width: 500%; height: 100%;}.img-list li{ float: left; width: 700px; height: 100%;}.img-list li:nth-of-type(1){ background: url("images/01.jpg") no-repeat center/cover;}.img-list li:nth-of-type(2){ background: url("images/02.png") no-repeat center/cover;}.img-list li:nth-of-type(3){ background: url("images/03.png") no-repeat center/cover;}.img-list li:nth-of-type(4){ background: url("images/04.png") no-repeat center/cover;}.img-list li:nth-of-type(5){ background: url("images/01.jpg") no-repeat center/cover;}.tab-list{ right: 0; bottom: 10px; width: 100px; margin: auto;}.tab-list:after{ content: ""; display: block; clear: both;}.tab-list li{ float: left; transition: 1s; width: 15px; height: 15px; margin-left: 5px; background-color: #bbb; border-radius: 50%;}.tab-list li:hover{ cursor: pointer;}.tab-list li:first-child{ margin-left: 0;}.tab-list .on{ width: 40px; border-radius: 8px;}- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
<!-- html代码 --><div class="wrap"> <div class="btn left"><</div> <div class="btn right">></div> <ul class="img-list"> <li></li> <li></li> <li></li> <li></li> <li></li> </ul> <ul class="tab-list"> <li class="on"></li> <li></li> <li></li> <li></li> </ul></div>- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
//js代码(function(){ var oImgList = document.getElementsByClassName("img-list")[0], aButton = document.getElementsByClassName("btn"), aImgLi = document.querySelectorAll(".img-list li"), oWidth = parseFloat(getComputedStyle(aImgLi[0]).width), oWrap = document.getElementsByClassName("wrap")[0], aTab = document.querySelectorAll(".tab-list li"); len = aImgLi.length, index = 0; function throttle(fn,time){ var startTime = new Date(); return function(){ var time_ = (new Date() - startTime) >= time; if(time_){ fn.apply(this); startTime = new Date(); } } } function btnTab(){ var t = new Date(); for(var i = 0,tabLen = aTab.length;i < tabLen;i++){ (function(i){ aTab.onclick = function(){ if(new Date() - t >= 1000){ aTab[index].className = ""; if((i - index) === (tabLen - 1)){ oImgList.style.transition = 0 + "s"; oImgList.style.left = -oWidth*(len-1) + "px"; index = len - 2; setTimeout(function(){ oImgList.style.transition = 1 + "s"; oImgList.style.left = -oWidth*(index) + "px"; },1000/60); } else if((i - index) === (1 - tabLen)){ oImgList.style.left = -oWidth*(len - 1) + "px"; index = 0; setTimeout(function(){ oImgList.style.transition = 0 + "s"; oImgList.style.left = index + "px"; },1000); } else{ oImgList.style.left = -oWidth*(i) + "px"; oImgList.style.transition = 1 + "s"; } index = i; this.className = "on"; t = new Date(); } } })(i); } } function btnPre(){ index--; if(index < 0){ oImgList.style.transition = 0 + "s"; oImgList.style.left = -oWidth*(len-1) + "px"; aTab[0].className = ""; index = len - 2; aTab[index].className = "on"; setTimeout(function(){ oImgList.style.transition = 1 + "s"; oImgList.style.left = -oWidth*(index) + "px"; },1000/60); } else{ oImgList.style.transition = 1 + "s"; oImgList.style.left = -oWidth*(index) + "px"; aTab[index + 1].className = ""; aTab[index].className = "on"; } } function btnNext(){ index++; oImgList.style.transition = 1 + "s"; if(index === len-1){ oImgList.style.left = -oWidth*index + "px"; aTab[len - 2].className = ""; index = 0; aTab[index].className = "on"; setTimeout(function(){ oImgList.style.transition = 0 + "s"; oImgList.style.left = index + "px"; },1000); } else{ oImgList.style.left = -oWidth*index + "px"; aTab[index - 1].className = ""; aTab[index].className = "on"; } } aButton[0].onclick = throttle(btnPre,1000); aButton[1].onclick = throttle(btnNext,1000); btnTab(); var timer = setInterval(btnNext,5000); oWrap.onmouseover = function(){ clearInterval(timer); } oWrap.onmouseout = function(){ timer = setInterval(btnNext,5000); } })();- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
[url=https://htmlpreview.github.io/?https://raw.githubusercontent.co ... BD%AE%E6%92%AD.html]无缝轮播演示demo[/url] 四、无缝轮播的改进在上面的无缝轮播中,可以发现对于不是相邻的两张图片的切换也并不是直接切换的,而是会过渡中间的图片再切换到目标图片,如下图:
解决办法就是把除了当前显示的图片全都设置成display:none,这样做的好处就是display:none的元素不占据位置!比如说从第一张切换到第三张,因为第二张是display:none,第三章需要显示所以display:block,由于第二张图片不占据位置的原因第三张图片会在第一张图片之后,因此就达到了从第一张直接切换到第三张的效果。
(有overflow:hidden)
/* css代码 */body{ background-color: #333;}ul{ position: absolute; left: 0; list-style: none; padding: 0;}.wrap{ overflow: hidden; position: relative; width: 700px; height: 450px; margin: 100px auto 0;}.wrap .btn{ position: absolute; top: 50%; z-index: 1; width: 50px; height: 80px; margin-top: -40px; background-color: rgba(0,0,0,.5); color: #fff; text-align: center; line-height: 80px; cursor: pointer;}.wrap .left{ left: 0;}.wrap .right{ right: 0;}.img-list{ top: 0; margin: 0; width: 500%; height: 100%;}.img-list li{ display: none; float: left; width: 700px; height: 100%;}.img-list .active{ display: block;}.img-list li:nth-of-type(1){ background: url("images/01.jpg") no-repeat center/cover;}.img-list li:nth-of-type(2){ background: url("images/02.png") no-repeat center/cover;}.img-list li:nth-of-type(3){ background: url("images/03.png") no-repeat center/cover;}.img-list li:nth-of-type(4){ background: url("images/04.png") no-repeat center/cover;}.img-list li:nth-of-type(5){ background: url("images/01.jpg") no-repeat center/cover;}.tab-list{ right: 0; bottom: 10px; width: 100px; margin: auto;}.tab-list:after{ content: ""; display: block; clear: both;}.tab-list li{ float: left; transition: 1s; width: 15px; height: 15px; margin-left: 5px; background-color: #bbb; border-radius: 50%;}.tab-list li:hover{ cursor: pointer;}.tab-list li:first-child{ margin-left: 0;}.tab-list .on{ width: 40px; border-radius: 8px;}- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
<!-- html代码 --><div class="wrap"> <div class="btn left"><</div> <div class="btn right">></div> <ul class="img-list"> <li class="active"></li> <li></li> <li></li> <li></li> <li></li> </ul> <ul class="tab-list"> <li class="on"></li> <li></li> <li></li> <li></li> </ul></div>- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
//js代码(function(){ var oImgList = document.getElementsByClassName("img-list")[0], aButton = document.getElementsByClassName("btn"), aImgLi = document.querySelectorAll(".img-list li"), oWidth = parseFloat(getComputedStyle(aImgLi[0]).width), oWrap = document.getElementsByClassName("wrap")[0], aTab = document.querySelectorAll(".tab-list li"); len = aImgLi.length, index = 0, index_ = 0; function throttle(fn,time){ var startTime = new Date(); return function(){ var time_ = (new Date() - startTime) >= time; if(time_){ fn.apply(this); startTime = new Date(); } } } function btnTab(){ var t = new Date(), direction; for(var i = 0,tabLen = aTab.length;i < tabLen;i++){ (function(i){ aTab.onclick = function(){ if(new Date() - t >= 1000){ index_ = index; i - index > 0 ? direction = true : direction = false; if(this.className !== "on"){ aTab[index].className = ""; if((i - index) === (tabLen - 1)){ aImgLi[len - 1].className = "active"; aImgLi[0].className = ""; oImgList.style.transition = 0 + "s"; oImgList.style.left = -oWidth + "px"; aTab[0].className = ""; index = len - 2; aImgLi[index].className = "active"; setTimeout(function(){ oImgList.style.transition = 1 + "s"; oImgList.style.left = 0 + "px"; },1000/60); setTimeout(function(){ aImgLi[len - 1].className = ""; },1000); } else if((i - index) === (1 - tabLen)){ oImgList.style.transition = 1 + "s"; oImgList.style.left = -oWidth + "px"; aTab[len - 2].className = ""; aImgLi[len - 1].className = "active"; index = 0; aTab[index].className = "on"; setTimeout(function(){ oImgList.style.transition = 0 + "s"; oImgList.style.left = index + "px"; aImgLi[index].className = "active"; aImgLi[len-2].className = ""; aImgLi[len-1].className = ""; },1000); } else{ if(direction){ oImgList.style.left = -oWidth + "px"; oImgList.style.transition = 1 + "s"; setTimeout(function(){ aImgLi[index_].className = ""; oImgList.style.left = 0 + "px"; oImgList.style.transition = 0 + "s"; },1000); } else{ oImgList.style.transition = 0 + "s"; oImgList.style.left = -oWidth + "px"; aImgLi[index].className = "active"; setTimeout(function(){ oImgList.style.transition = 1 + "s"; oImgList.style.left = 0 + "px"; },1000/60); setTimeout(function(){ aImgLi[index_].className = ""; },1000); } index = i; aImgLi[index].className = "active"; } this.className = "on"; t = new Date(); } } } })(i); } } function btnPre(){ index--; if(index < 0){ aImgLi[len - 1].className = "active"; aImgLi[0].className = ""; oImgList.style.transition = 0 + "s"; oImgList.style.left = -oWidth + "px"; aTab[0].className = ""; index = len - 2; aImgLi[index].className = "active"; aTab[index].className = "on"; setTimeout(function(){ oImgList.style.transition = 1 + "s"; oImgList.style.left = 0 + "px"; },1000/60); setTimeout(function(){ aImgLi[len - 1].className = ""; },1000); } else{ oImgList.style.transition = 0 + "s"; oImgList.style.left = -oWidth + "px"; aTab[index + 1].className = ""; aTab[index].className = "on"; aImgLi[index].className = "active"; setTimeout(function(){ oImgList.style.transition = 1 + "s"; oImgList.style.left = 0 + "px"; },1000/60); setTimeout(function(){ aImgLi[index + 1].className = ""; },1000); } } function btnNext(){ index++; oImgList.style.transition = 1 + "s"; if(index === len-1){ oImgList.style.left = -oWidth + "px"; aTab[len - 2].className = ""; aImgLi[index].className = "active"; index = 0; aTab[index].className = "on"; setTimeout(function(){ oImgList.style.transition = 0 + "s"; oImgList.style.left = index + "px"; aImgLi[index].className = "active"; aImgLi[len-2].className = ""; aImgLi[len-1].className = ""; },1000); } else{ oImgList.style.left = -oWidth + "px"; aTab[index - 1].className = ""; aTab[index].className = "on"; aImgLi[index].className = "active"; setTimeout(function(){ oImgList.style.transition = 0 + "s"; aImgLi[index - 1].className = ""; oImgList.style.left = 0 + "px"; },1000); } } aButton[0].onclick = throttle(btnPre,1000); aButton[1].onclick = throttle(btnNext,1000); btnTab(); var timer = setInterval(btnNext,5000); oWrap.onmouseover = function(){ clearInterval(timer); } oWrap.onmouseout = function(){ timer = setInterval(btnNext,5000); } })();- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
[url=https://htmlpreview.github.io/?https://raw.githubusercontent.co ... 9E%81%E7%89%88.html]改进后的无缝轮播demo演示[/url] 五、结束语本文仅仅提到了无缝轮播,其实还有很多优秀的轮播效果,但是由于目前能力有限,还驾驭不了~所以就到这里啦,总之任重而道远,最后感谢阅读咯~
|