輪播,無論是文字輪播還是圖片輪播,他們的原理是一樣的,都是通過定時器執行循環展示和影藏。
一、手動輪播
(1)原理
一系列的大小相等的圖片平鋪,利用CSS布局只顯示一張圖片,其余隱藏。通過計算偏移量利用定時器實現自動播放,或通過手動點擊事件切換圖片。
(2)實現
如何利用css實現布局顯示一張圖片?主要的屬性是over-follow:hidden。首先給容器一個固定的長和寬,然后設置over-flow:hidden。
1、html結構
首先父容器container存放所有內容,子容器list存在圖片。子容器buttons存放按鈕小圓點。
<div id="container"> <div id="list" style="left: -600px;"> <img src="img/5.png" alt="1" /> <img src="img/1.png" alt="1" /> <img src="img/2.png" alt="2" /> <img src="img/3.png" alt="3" /> <img src="img/4.png" alt="4" /> <img src="img/5.png" alt="5" /> <img src="img/1.png" alt="5" /> </div> <div id="buttons"> <span index="1" class="on"></span> <span index="2"></span> <span index="3"></span> <span index="4"></span> <span index="5"></span> </div> <a href="javascript:;" id="prev" class="arrow"><</a> <a href="javascript:;" id="next" class="arrow">></a> </div>
優化,無縫滾動。
當你從最后一張圖切換回第一張圖時,有很大空白,利用兩張輔助圖來填補這個空白。
這里補充下無縫滾動,直接看代碼,復制最后一張圖片放置第一張圖片前,同時復制第一張圖片放置最后一張圖片的后面。并且,將第一張圖片輔助圖(實際上是實際顯示的第5張圖片隱藏起來,故設置style="left: -600px;")
2、css樣式
1、對盒子模型,文檔流的理解,絕對定位問題。
2、注意list的overflow:hidden;只顯示窗口的一張圖片,把左右兩邊的都隱藏起來。
3、確保buttons中每個span所在層置頂,將其設置為最頂端。
* { margin: 0; padding: 0; text-decoration: none; } body { padding: 20px; } #container { position: relative; width: 600px; height: 400px; border: 3px solid #333; overflow: hidden; } #list { position: absolute; z-index: 1; width: 4200px; height: 400px; } #list img { float: left; width: 600px; height: 400px; } #buttons { position: absolute; left: 250px; bottom: 20px; z-index: 2; height: 10px; width: 100px; } #buttons span { float: left; margin-right: 5px; width: 10px; height: 10px; border: 1px solid #fff; border-radius: 50%; background: #333; cursor: pointer; } #buttons .on { background: orangered; } .arrow { position: absolute; top: 180px; z-index: 2; display: none; width: 40px; height: 40px; font-size: 36px; font-weight: bold; line-height: 35px; text-align: center; color: #fff; background-color: RGBA(0, 0, 0, .3); cursor: pointer; } .arrow:hover { background-color: RGBA(0, 0, 0, .7); } #container:hover .arrow { display: block; } #prev { left: 20px; } #next { right: 20px; }
3、JS實現
首先我們先實現出手動點擊左右兩個箭頭切換圖片的效果:
window.onload = function() { var list = document.getElementById('list'); var prev = document.getElementById('prev'); var next = document.getElementById('next'); function animate(offset) { //獲取的是style.left,是相對左邊獲取距離,所以第一張圖后style.left都為負值, //且style.left獲取的是字符串,需要用parseInt()取整轉化為數字。 var newLeft = parseInt(list.style.left) + offset; list.style.left = newLeft + 'px'; if(newLeft<-3000){ list.style.left = -600 + 'px'; } if(newLeft>-600){ list.style.left = -3000 + 'px'; } } prev.onclick = function() { animate(600); } next.onclick = function() { animate(-600); } }
效果如下圖所示
運行后我們會發現,一直點擊右箭頭 ,會出現空白,而且,不能回到第一張圖片。要點擊左箭頭才能回到第一張圖片。
原因是我們利用偏移量left來獲取圖片,當看到left值小于3600時,因為沒有第8張圖片就出現空白,所以這里我們需要對偏移量做一個判斷。
if(newLeft<-3000){ list.style.left = -600 + 'px'; } if(newLeft>-600){ list.style.left = -3000 + 'px'; }
加了這個判斷就是說,在實時的left值在小于-3000的時候,通過操作dom元素直接把left值給到-600,回到初始化的狀態。
但是輪播有自動輪播和手動輪播。上面基本實現的是手動點擊進行輪播(手動輪播)。
二、自動輪播
要實現自動,必須有定時器進行計時。
對于定時器,有必要說明一下setInterval()跟setTimeout的區別了。
簡單來說,setInterval()執行多次,setTimeout()只執行一次。
所以自動輪播需要我們每隔一段時間執行一次,選擇setInterval()函數。
/*自動循環播放*/ var timer; function play(){ timer = setInterval(function(){ prev.onclick(); },1500) } play();
完美實現了自動輪播
但是,當我們想仔細看某一張圖片時候,要把圖片停住,我們清楚定時器就可以
三、手動可以干預輪播
我想仔細看某一張照片時候,要圖片停住,需要用到window.clearInterval 這個方法。
這里,我們需要對其DOM操作,需要獲取整個輪播圖區域,鼠標進入到容器區域就清空計時器。
/*鼠標放上(離開)對應輪播暫停(播放)*/ var container = document.getElementById('container'); function stop() { clearInterval(timer); } container.onmouseover = stop; container.onmouseout = play;
效果,如下圖所示:
一個鼠標放上輪播暫停的實現就完美實現了。
現在回顧一下,的確很簡單,不是很難,并不是必須要用插件實現,原生的js也可以實現,你可以優化一下封裝成自己的輪播插件。
(1)容器的css布局。
(2)每一次輪播通過偏移量left實現,手動輪播的按鈕綁定每一次偏移量增加還是減少一張照片寬度的偏移量。
(3)自動輪播,通過setInterval()方法實現定時器,執行下一張的點擊函數
(4)鼠標控制輪播的暫停和繼續。通過onmouseover為暫停,onmouseout為繼續。
完整代碼:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <style type="text/css"> * { margin: 0; padding: 0; text-decoration: none; } body { padding: 20px; } #container { position: relative; width: 600px; height: 400px; border: 3px solid #333; overflow: hidden; } #list { position: absolute; z-index: 1; width: 4200px; height: 400px; } #list img { float: left; width: 600px; height: 400px; } #buttons { position: absolute; left: 250px; bottom: 20px; z-index: 2; height: 10px; width: 100px; } #buttons span { float: left; margin-right: 5px; width: 10px; height: 10px; border: 1px solid #fff; border-radius: 50%; background: #333; cursor: pointer; } #buttons .on { background: orangered; } .arrow { position: absolute; top: 180px; z-index: 2; display: none; width: 40px; height: 40px; font-size: 36px; font-weight: bold; line-height: 35px; text-align: center; color: #fff; background-color: RGBA(0, 0, 0, .3); cursor: pointer; } .arrow:hover { background-color: RGBA(0, 0, 0, .7); } #container:hover .arrow { display: block; } #prev { left: 20px; } #next { right: 20px; } </style> </head> <body> <div id="container"> <div id="list" style="left: -600px;"> <img src="img/5.png" alt="1" /> <img src="img/1.png" alt="1" /> <img src="img/2.png" alt="2" /> <img src="img/3.png" alt="3" /> <img src="img/4.png" alt="4" /> <img src="img/5.png" alt="5" /> <img src="img/1.png" alt="5" /> </div> <div id="buttons"> <span index="1" class="on"></span> <span index="2"></span> <span index="3"></span> <span index="4"></span> <span index="5"></span> </div> <a href="javascript:;" id="prev" class="arrow"><</a> <a href="javascript:;" id="next" class="arrow">></a> </div> </body> </html> <script> window.onload = function() { var list = document.getElementById('list'); var prev = document.getElementById('prev'); var next = document.getElementById('next'); function animate(offset) { /*獲取的是style.left,是相對左邊獲取距離,所以第一張圖后style.left都為負值, 且style.left獲取的是字符串,需要用parseInt()取整轉化為數字。*/ var newLeft = parseInt(list.style.left) + offset; list.style.left = newLeft + 'px'; if(newLeft < -3000) { list.style.left = -600 + 'px'; } if(newLeft > -600) { list.style.left = -3000 + 'px'; } } /*上一步*/ prev.onclick = function() { animate(600); } /*下一步*/ next.onclick = function() { animate(-600); } /*自動循環播放*/ var timer; function play() { timer = setInterval(function() { prev.onclick(); }, 1500) } play(); /*鼠標放上(離開)對應輪播暫停(播放)*/ var container = document.getElementById('container'); function stop() { clearInterval(timer); } container.onmouseover = stop; container.onmouseout = play; } </script>
四、小點也隨著圖片進行輪播
首先要能拿到有多少個小點的數組,然后每一次的下一步的時候判斷一下當前的小圓點的標志位。
(1)當標志位大于數組的長度時候,需要把標志位賦值為初始值
/*上一步*/ prev.onclick = function() { index = index -1; if(index < 1) { index = 5; } buttonShow(); animate(600); } /*下一步*/ next.onclick = function() { index = index + 1; if(index > 5) { index = 1; } buttonShow(); animate(-600); }
(2)每執行一次下一步,標志位temp+1,同時將圓點的上一個樣式清除,下一個顯示選中樣式。
function buttonShow() { /*console.log(buttons.length);*/ /*清除之前的樣式*/ for(var i = 0; i < buttons.length; i++) { if(buttons[i].className === 'on') { buttons[i].className = ''; } } /*數組從0開始,temp從-1開始*/ buttons[index - 1].className = 'on'; }
最后效果如下圖所示:
五、小點可以點擊到對應的圖片上
突然發現圖片下邊還有一堆小點,需要給增加點擊事件,點擊哪一個點,就到哪一張圖片上。
/*小圓點的點擊事件*/ for(var i =0;i<buttons.length;i++){ buttons[i].onclick = function (){ console.log(i); /*偏移量的獲取:獲取鼠標的小圓點的位置,用this把index綁定到對象buttons[i]上*/ /*由于index是自定義屬性,需要用到getAttribute()這個dom的2級方法,去獲取自定義的index屬性*/ var clickIndex = parseInt(this.getAttribute('index')); var offset = 600*(index-clickIndex); animate(offset); index = clickIndex; buttonShow(); } }
要大功告成了,但是發現控制臺會發現打印出來的永遠的是i=5。
“對javascript來說,由for語句創建的變量i即使在for循環執行結束后,也依舊會存在于循環外部的執行環境中。”
就是說,js沒有塊級作用域這東西,(可能我C寫多了,混淆了)。在第一次循環(從 i=0 到 4 這一過程)結束后,最后的 i 獲取到的為 buttons.length 的值被
保存在for循環之外,最后鼠標點擊任何一個小圓點時,自然訪問的一直是 i=5 了。
使用立即函數
/*小圓點的點擊事件*/ for(var i = 0; i < buttons.length; i++) { /*使用立即函數*/ (function(i) { buttons[i].onclick = function() { console.log(i); /*偏移量的獲取:獲取鼠標的小圓點的位置,用this把index綁定到對象buttons[i]上*/ /*由于index是自定義屬性,需要用到getAttribute()這個dom的2級方法,去獲取自定義的index屬性*/ var clickIndex = parseInt(this.getAttribute('index')); var offset = 600 * (index - clickIndex); animate(offset); index = clickIndex; buttonShow(); } })(i) }
這里涉及到js的閉包問題。
完美原生js實現輪播,原理以及實踐。總結一下:
原理:(1)使用的是css只顯示一張圖片,其余隱藏。通過計算偏移量利用定時器實現自動播放,或通過手動點擊事件切換圖片。
實踐:http://www.mwcxs.top/%E8%BD%AE%E6%92%AD/index.html
歡迎訪問:
1、云商城isv系統http://isv.suningcloud.com/mpisv-web/index
2、云商城消費者門戶http://www.suningcloud.com/promotion/index/experience_center.html
文章列表
留言列表