大家平時逛淘寶網的時候,在首頁就能看到焦點圖輪播的效果,就是這個樣子的:
PS:想起每每打開淘寶,總會被這個玩意先奪眼球,偶爾還去點進去溜溜,幸好我定力好,總能控制住自己的購買欲望,為自己不用剁手感到欣慰 ! 好吧,其實說白了就是窮,就是沒錢,就是不能好好地任性,所以只能先去慕課網找教程學習把它給做出來!
OK,首先將HTML結構搭建好先:
<div id="container"> <div id="list" style="left: -600px;"> <img src="img/5.jpg" alt="1"/> <img src="img/1.jpg" alt="1"/> <img src="img/2.jpg" alt="2"/> <img src="img/3.jpg" alt="3"/> <img src="img/4.jpg" alt="4"/> <img src="img/5.jpg" alt="5"/> <img src="img/1.jpg" 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>
最外層div就是容器啦,然后其子元素分別就是存放圖片的id為list的div,存放小圓圈按鈕的id為buttons的div,最后兩個a標簽就是左右切換的按鈕。還有一個問題需要注意,此焦點圖輪播器其實只有五張圖,但是在id為list的div里卻放了七張圖,這是為啥呢?其原理是:第一張圖片(5.jpg)和最后一張圖片(1.jpg)的作用是為了實現無限滾動的效果,因為此效果是通過設置id為list的div容器的left值來實現圖片切換的,所以當輪播到第五張圖片(5.jpg)的時候,再進行向右切換的時候,這時最后一張圖片被切換進來,此時left值已經為-3600px,並且同時我們又將其left值改為-600px,這樣就回到了真正的第一張圖。由於最后一張圖片就是第一張圖片(1.jpg),所以用戶肉眼看上去沒有什么變化,就這樣實現了無限滾動的效果,其他同理!那么如果沒有那兩張圖片作為過渡的話,效果就會是這樣,當輪播到最后一張的時候會閃一下就沒有了:
設置CSS樣式:
*{ margin: 0; padding: 0; } a{ text-decoration: none; } body { padding: 20px; } #container { width: 600px; /*這里600x400是圖片的寬高*/ height: 400px; border: 3px solid #333; overflow: hidden; /*隱藏溢出的圖片,因為圖片左浮動,總寬度為4200*/ position: relative; } #list { width: 4200px; /*這里設置7張圖片總寬度*/ height: 400px; position: absolute; /*基於父容器container進行定位*/ z-index: 1; } #list img { float: left; } #buttons { position: absolute; height: 10px; width: 100px; z-index: 2; /*按鈕在圖片的上面*/ bottom: 20px; left: 250px; } #buttons span { cursor: pointer; float: left; border: 1px solid #fff; width: 10px; height: 10px; border-radius: 50%; background: #333; margin-right: 5px; } #buttons .on { background: orangered; /*選中的按鈕樣式*/ } .arrow { cursor: pointer; display: none; /*左右切換按鈕默認先隱藏*/ line-height: 39px; text-align: center; font-size: 36px; font-weight: bold; width: 40px; height: 40px; position: absolute; z-index: 2; top: 180px; background-color: RGBA(0,0,0,.3); color: #fff; } .arrow:hover { background-color: RGBA(0,0,0,.7); } #container:hover .arrow { display: block; /*當鼠標放上去容器上面就顯示左右切換按鈕*/ } #prev { left: 20px; } #next { right: 20px; }
樣式不難,主要就是根據實際情況修改一下圖片尺寸就行了。因為圖片組都左浮動,所以寬度遠遠大於父容器的寬度,如果沒有設置overflow: hidden; 效果就是這樣子:
好了,最重要的還是JS實現輪播效果:
首先來實現最簡單的通過左右按鈕來實現切換:
window.onload = function () { var container = document.getElementById('container'); var list = document.getElementById('list'); var buttons = document.getElementById('buttons').getElementsByTagName('span'); var prev = document.getElementById('prev'); var next = document.getElementById('next'); //切換動畫 function animate (offset) { list.style.left = parseInt(list.style.left) + offset+ 'px'; } next.onclick = function () { animate(-600); } prev.onclick = function () { animate(600); } }
這樣就能簡單的實現了切換效果,但是當切換到最后一張再向右切換時就會出現上面所講的空白的現象,所以呢,就需要通過判斷list的left值如果大於-600(-600是默認設置的,為了顯示第一張圖片[1.jpg])就將其設置為-3000,如果小於-3000,就將其設置為-600,這樣就能實現無線滾動了,但是又會發現當圖片切換滾動的時候,小按鈕並沒有跟着改變,這時我們就需要通過一個index值(默認為1)來索引當前是哪個小按鈕被選中,並為其添加.on的類,在添加之前需要將原先有.on的小按鈕的class移除掉,最后一點是由於小按鈕只有五個,想要實現無限切換,就需要判斷邊界值,當index為1時,如果還想往左切換的話,就將其設置為5,這樣就會回到第五個小按鈕上,其他同理。
window.onload = function () { var container = document.getElementById('container'); var list = document.getElementById('list'); var buttons = document.getElementById('buttons').getElementsByTagName('span'); var prev = document.getElementById('prev'); var next = document.getElementById('next'); var index = 1; //用於索引當前按鈕 function animate (offset) { 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';
}
} //用於為按鈕添加樣式 function showButton() { //先找出原來有.on類的按鈕,並移除其類 for (var i = 0; i < buttons.length ; i++) { if( buttons[i].className == 'on'){ buttons[i].className = ''; break; } } //為當前按鈕添加類,索引下標從0開始,故需減1 buttons[index - 1].className = 'on'; } next.onclick = function () { if (index == 5) { index = 1; } else { index += 1; } animate(-600); showButton(); } prev.onclick = function () { if (index == 1) { index = 5; } else { index -= 1; } animate(600); showButton(); } }
接下來需要通過點擊小按鈕來實現切換效果,不像左右切換,按鈕是可以隨意點擊進行切換的,比如從第一個按鈕直接點擊第五個按鈕,這樣的話,就不是每次都是-600的間隔了,我們因此還需要獲取當前點擊的按鈕和之前的按鈕的index值的差值,然后乘以-600得到的才是真正的偏移量,並且同時點擊的時候,為該按鈕添加選中樣式類。但是如何知道當前點擊的是哪個按鈕呢,還記得我們在按鈕的span標簽里設置了自定義屬性index嗎,其值分別對應每個按鈕的索引值,這樣當點擊按鈕時通過獲取該按鈕的index屬性值即可知道是哪個按鈕,最后一點就是當繼續點擊當前按鈕時,比如此時輪播到第一張圖片,你再點擊對應的第一個按鈕,應該阻止再次切換,做到優化。
window.onload = function () { var container = document.getElementById('container'); var list = document.getElementById('list'); var buttons = document.getElementById('buttons').getElementsByTagName('span'); var prev = document.getElementById('prev'); var next = document.getElementById('next'); var index = 1; //用於索引當前按鈕 function animate (offset) {
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';
}
} //用於為按鈕添加樣式 function showButton() { //先找出原來有.on類的按鈕,並移除其類 for (var i = 0; i < buttons.length ; i++) { if( buttons[i].className == 'on'){ buttons[i].className = ''; break; } } //為當前按鈕添加類 buttons[index - 1].className = 'on'; } next.onclick = function () { if (index == 5) { index = 1; } else { index += 1; } animate(-600); showButton(); } prev.onclick = function () { if (index == 1) { index = 5; } else { index -= 1; } animate(600); showButton(); } //通過循環為按鈕添加點擊事件 for (var i = 0; i < buttons.length; i++) { buttons[i].onclick = function () { //當繼續點擊當前按鈕的時候,不進行切換 if(this.className == 'on') { return; } //通過獲取按鈕標簽的自定義屬性index,得到索引值,再而計算差值 var myIndex = parseInt(this.getAttribute('index')); //真正的便宜量 var offset = -600 * (myIndex - index); animate(offset); //將點擊按鈕的index屬性值設置為當前的index值 index = myIndex; showButton(); } } }
接着實現平滑切換的效果,之前已經實現的效果是直接切換,而我們想要的是能夠平滑過渡,體驗會好一些。主要實現方法是通過定時器setTimeout。設置切換需要的總時間,每次間隔多少時間,然后求出每次切換過渡的位移量,判斷是否到達目標值,若否,則繼續執行定時器進行位移。還有一點就是,如果連續點擊切換按鈕,圖片會立刻不停地切換, 但我們想要的效果是等當前圖片切換完成之后再進行下一次切換,這個可以優化一下。最后實現自動播放效果,當鼠標不點擊時,它能自動播放,這里用到setInterval定時器,每次3秒執行一次點擊事件,而當鼠標移上去的時候清除該事件,離開的時候又自動播放。OK,整理一下代碼:
window.onload = function () { var container = document.getElementById('container'); var list = document.getElementById('list'); var buttons = document.getElementById('buttons').getElementsByTagName('span'); var prev = document.getElementById('prev'); var next = document.getElementById('next'); var index = 1; //用於索引當前按鈕 var len = 5; //圖片的數量 var animated = false; //用於判斷切換是否進行 var interval = 3000; //自動播放定時器秒數,這里是3秒 var timer; //定時器 function animate (offset) { animated = true; //切換進行中 var time = 300; //位移總時間 var inteval = 10; //位移間隔時間 var speed = offset/(time/inteval); //每次位移量 var left = parseInt(list.style.left) + offset; //目標值 var go = function (){ //這兩種情況表示還在切換中 if ( (speed > 0 && parseInt(list.style.left) < left) || (speed < 0 && parseInt(list.style.left) > left)) { list.style.left = parseInt(list.style.left) + speed + 'px'; setTimeout(go, inteval); //繼續執行切換go()函數 } else { list.style.left = left + 'px'; if(left>-600){ list.style.left = -600 * len + 'px'; } if(left<(-600 * len)) { list.style.left = '-600px'; } animated = false; //切換完成 } } go(); } //用於為按鈕添加樣式 function showButton() { //先找出原來有.on類的按鈕,並移除其類 for (var i = 0; i < buttons.length ; i++) { if( buttons[i].className == 'on'){ buttons[i].className = ''; break; } } //為當前按鈕添加類 buttons[index - 1].className = 'on'; } //自動播放 function play() { timer = setTimeout(function () { next.onclick(); play(); }, interval); } //清除定時器 function stop() { clearTimeout(timer); } //右點擊 next.onclick = function () { if (animated) { //如果切換還在進行,則直接結束,直到切換完成 return; } if (index == 5) { index = 1; } else { index += 1; } animate(-600); showButton(); } //左點擊 prev.onclick = function () { if (animated) { //如果切換還在進行,則直接結束,直到切換完成 return; } if (index == 1) { index = 5; } else { index -= 1; } animate(600); showButton(); } for (var i = 0; i < buttons.length; i++) { buttons[i].onclick = function () { if (animated) { //如果切換還在進行,則直接結束,直到切換完成 return; } if(this.className == 'on') { //如果點擊的按鈕是當前的按鈕,不切換,結束 return; } //獲取按鈕的自定義屬性index,用於得到索引值 var myIndex = parseInt(this.getAttribute('index')); var offset = -600 * (myIndex - index); //計算總的位移量 animate(offset); index = myIndex; //將新的索引值賦值index showButton(); } } container.onmouseover = stop;//父容器的移入移出事件 container.onmouseout = play; play(); //調用自動播放函數 }
OK, 這樣就做完了,如果還不理解,可以直接去慕課網看一下教程:http://www.imooc.com/learn/18