本文實(shí)例講述了原生JS實(shí)現(xiàn)的輪播圖功能。分享給大家供大家參考,具體如下:
一、效果預(yù)覽:
由于只能上傳2M以下的圖片,這里只截取了自動(dòng)切換的效果:
二、編寫(xiě)語(yǔ)言
HTML、CSS、原生JS
三、編寫(xiě)思路
(一)HTML部分
1、.slide
意為滑槽,里面存放所有圖片;
2、.prev
存放向左的箭頭,.next存放向右的箭頭;
3、pointer
意為指示器,存放下方的五個(gè)切換按鈕,每個(gè)切換按鈕用span來(lái)表示;
4、.m-view
,意為視窗,即每次看到圖片的窗口,它存放以上所有的部件;
(二)CSS部分
1、.m-view
設(shè)為相對(duì)定位,他的后代元素可以以它作為絕對(duì)定位的參照;
2、.slide
、.prev
、.next
、pointer
全都用絕對(duì)定位放到合適位置;
3、.slide
的所有圖片水平排列,且視窗.m-view
的寬度設(shè)為只有一張圖片那么寬,這樣默認(rèn)情況.slide
還是會(huì)全部顯示;當(dāng)給.m-view
設(shè)置overflow:hidden
后子元素超出它的部分就會(huì)隱藏,就實(shí)現(xiàn)了只顯示一張圖片的效果;
(三)JS部分
1、切換功能:
設(shè)置一個(gè)切換函數(shù)toggle實(shí)現(xiàn)左切或者右切一張圖,toggle有兩個(gè)子函數(shù)leftToggle和rightToggle分別實(shí)現(xiàn)向左、向右切換一張圖,將他們分別綁定到.prev
和.next
按鈕的clik事件;
2、切換功能的淡入動(dòng)畫(huà)效果
只有1的話切換是立即產(chǎn)生的,沒(méi)有過(guò)渡效果;這里利用定時(shí)器和步長(zhǎng)將切換功能細(xì)化到更小的滑動(dòng)操作leftStep和rightStep,leftToggle和rightToggle通過(guò)多次調(diào)用滑動(dòng)操作來(lái)實(shí)現(xiàn)一次切換,這樣就會(huì)產(chǎn)生動(dòng)畫(huà)效果;
3、跳轉(zhuǎn)功能
對(duì)指示器的每個(gè)圓形按鈕綁定跳轉(zhuǎn)功能,跳轉(zhuǎn)實(shí)際上是將.slide進(jìn)行移動(dòng);
4、自動(dòng)播放
只需要設(shè)置定時(shí)器,每隔一定時(shí)間執(zhí)行切換即可;
四、我的代碼
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 171 172 173 | <!DOCTYPE html> <html lang= "en" > <head> <meta charset= "UTF-8" > <title>輪播圖</title> <style> .m-view,.m-view .slide img{ position: relative; /*作為絕對(duì)定位的父元素*/ width: 800px; height: 600px; } .m-view{ overflow: hidden; /*將超出該div的子元素隱藏*/ } .m-view .slide{ position: absolute; width: 8000px; height: 600px; } .m-view .slide img{ margin-right: -5px; } .m-view .prev,.m-view .next{ position: absolute; top: 40%; font: 60px/60px Microsoft YaHei; color: #00BFFF; } .m-view .prev{ left: 10px; } .m-view .next{ right: 10px; } .m-view .pointer{ position: absolute; bottom: 40px; left: 33%; } .m-view .pointer span{ display: inline-block; /*水平排列*/ width: 40px; height: 40px; border-radius: 20px; margin-right: 10px; background-color: #00FF00; } .m-view .pointer .on{ /*點(diǎn)亮當(dāng)前圖片對(duì)應(yīng)的圓圈*/ background-color: #1E90FF; } </style> </head> <body> <div class= "m-view" > <div class= "slide" style= "left: -800px" > <img src= "../lunbo/5.jpg" alt= "4" > <img src= "../lunbo/1.jpg" alt= "0" > <img src= "../lunbo/2.jpg" alt= "1" > <img src= "../lunbo/3.jpg" alt= "2" > <img src= "../lunbo/4.jpg" alt= "3" > <img src= "../lunbo/5.jpg" alt= "4" > <img src= "../lunbo/1.jpg" alt= "0" > </div> <div class= "prev" ><</div> <div class= "next" >></div> <div class= "pointer" > <span class= "button on" index= "0" ></span> <span class= "button" index= "1" ></span> <span class= "button" index= "2" ></span> <span class= "button" index= "3" ></span> <span class= "button" index= "4" ></span> </div> </div> <script type= "text/javascript" > var view=document.getElementsByClassName( 'm-view' )[0]; var slide=document.getElementsByClassName( 'slide' )[0]; var prev=document.getElementsByClassName( 'prev' )[0]; var next=document.getElementsByClassName( 'next' )[0]; var button=document.getElementsByClassName( 'button' ); var curIndex=0; //當(dāng)前圖片的索引位置 var toggled= true ; //是否正在切換,true表明切換已完成,此時(shí)才能切換 /* Toggle函數(shù)實(shí)現(xiàn)切換一張圖片的功能 */ function Toggle () { var TIMER=50; //滑動(dòng)一次所用的時(shí)間,它是setInterval的第二個(gè)參數(shù) var time=800; //每切換一張圖片總共用的時(shí)長(zhǎng) var times=time/TIMER; //每切換一張圖片需滑動(dòng)的次數(shù) var stepLenth=800/times; //每次滑動(dòng)的步長(zhǎng) var leftToggle= function () { var t1=times; function leftStep(){ slide.style.left=parseInt(slide.style.left)+stepLenth+ "px" ; t1--; if (!t1) { clearInterval(interval); curIndex--; if (curIndex<0) { slide.style.left=parseInt(slide.style.left)-4000+ "px" ; curIndex=4; }; toggled= true ; }; }; if (toggled== true ) { toggled= false ; button[curIndex].className= "button" ; if (curIndex!=0) { button[curIndex-1].className= "button on" ; } else { button[curIndex+4].className= "button on" ; } var interval=setInterval(leftStep,TIMER); }; }; var rightToggle= function () { var t2=times; function leftStep(){ slide.style.left=parseInt(slide.style.left)-stepLenth+ "px" ; t2--; if (!t2) { clearInterval(interval); curIndex++; if (curIndex>4) { slide.style.left=parseInt(slide.style.left)+4000+ "px" ; curIndex=0; }; toggled= true ; }; }; if (toggled== true ) { toggled= false ; button[curIndex].className= "button" ; if (curIndex!=4) { button[curIndex+1].className= "button on" ; } else { button[curIndex-4].className= "button on" ; }; var interval=setInterval(leftStep,TIMER); }; } this .leftToggle=leftToggle; //輸出對(duì)外的接口 this .rightToggle=rightToggle; }; var toggle= new Toggle(); prev.onclick= function () { toggle.leftToggle(); }; next.onclick= function () { toggle.rightToggle(); }; /* 點(diǎn)擊圓圈跳轉(zhuǎn)功能 */ for ( var i = 0; i < button.length; i++) { button[i].onclick= function () { var newIndex=parseInt( this .getAttribute( "index" )); if (newIndex!=curIndex) { var distance=-800*(newIndex-curIndex); slide.style.left=parseInt(slide.style.left)+distance+ "px" ; button[curIndex].className= "button" ; button[newIndex].className= "button on" ; curIndex=newIndex; }; }; } /* 自動(dòng)播放功能,鼠標(biāo)移上去停止播放,移開(kāi)再次播放 */ var intervalo=setInterval(toggle.rightToggle,3000); view.onmouseover= function () { clearInterval(intervalo); } view.onmouseout= function () { intervalo=setInterval(toggle.rightToggle,3000); } </script> </body> </html> |
五、一些總結(jié)
1、本次采用了面向?qū)ο蠛头庋b的思路,這是因?yàn)閭€(gè)人體會(huì)到確實(shí)面向?qū)ο蟮脑O(shè)計(jì)能使代碼編寫(xiě)思路更加清晰,還能夠免去很多冗余重復(fù)的代碼,也嘗試過(guò)其他書(shū)寫(xiě)思路,但都會(huì)使代碼變得不太直觀;要注意的一點(diǎn)就是封裝后要向外提供接口,且如果是封裝在一個(gè)函數(shù)中,需要實(shí)例化一個(gè)對(duì)象才能調(diào)用;
2、在.slide中設(shè)置了一個(gè)內(nèi)聯(lián)樣式,這是因?yàn)樵诤竺嬉@取并改變它的left屬性,如果不采用內(nèi)聯(lián)樣式的方法,將無(wú)法設(shè)置;因?yàn)槌跏紩r(shí).style.left只能獲取內(nèi)聯(lián)樣式,即使采用內(nèi)部樣式和外部樣式也會(huì)使得獲取的值為undefined。當(dāng)然,肯定也可以采用其他方法,但是似乎其他方案都更為復(fù)雜一些,沒(méi)找到更簡(jiǎn)便的方法。
3、在前后各多放置一張圖片的作用:
比如,當(dāng)前是圖片1,現(xiàn)在向左切換,可以和其他位置一樣先執(zhí)行統(tǒng)一的左移操作,這時(shí)視窗顯示額外放置的圖片5,再將.slide整體左移使真正的圖片5顯示在視窗中,這樣是先出現(xiàn)了動(dòng)畫(huà)效果再“暗中移動(dòng)”了.slide,就好像沒(méi)移動(dòng)一樣,真正做到了無(wú)縫切換,邏輯也很簡(jiǎn)單;如果不放置額外的圖片,就需要先將視窗左移,使圖片5顯示在視窗中,這樣動(dòng)畫(huà)效果難以設(shè)置。
4、在獲取每個(gè)span在它父元素的索引位置時(shí),采用了getAttribute
獲取自定義的index屬性的方法,其他方法肯定也有不少,但是肯定不能在循環(huán)中把i的值直接當(dāng)成span的索引位置。
5、在跳轉(zhuǎn)功能中,如果要跳轉(zhuǎn)的正是當(dāng)前的頁(yè)面,應(yīng)該什么也不做,這樣可以優(yōu)化性能 。
6、在點(diǎn)擊左右箭頭切換時(shí),先判斷上一次動(dòng)畫(huà)是否完成,沒(méi)完成就不切換,這樣可以優(yōu)化性能,否則連續(xù)點(diǎn)擊可能導(dǎo)致卡頓、切換效果不佳。
7、代碼似乎還有可以優(yōu)化的地方;
8、這個(gè)只是制作了一個(gè)輪播圖,接下來(lái)考慮做一個(gè)輪播組件,似乎難度要大些,還有3D的輪播效果也想要嘗試下了。
聯(lián)系客服