一般 Flash 廣告或是商品的輪播大多是不間斷的,所以就常會有網友問說 jQuery 的範例是否能做到不間斷的輪播呢?答案其實連想都不用想的也知道是可以的,且要達到同樣效果的方法有好幾種,筆者此次就針對一種較簡單但效能會差一點點的方式來介紹。
首先當然是要準備好 HTML(圖片還是一樣從梅干那邊 A 來的):
檢視原始碼 HTML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <body> <div id="abgne-block-20110406"> <div class="slides"> <ul> <li><a href="#"><img src="images/1.jpg" alt="" /></a></li> <li><a href="#"><img src="images/2.jpg" alt="" /></a></li> <li><a href="#"><img src="images/3.jpg" alt="" /></a></li> <li><a href="#"><img src="images/4.jpg" alt="" /></a></li> <li><a href="#"><img src="images/5.jpg" alt="" /></a></li> </ul> </div> <a href="#" class="prev"><</a> <a href="#" class="next">></a> </div> </body> |
這次的範例會多加一個外框,因此就會看到有多出一層來包裹 ul。接著就來看 CSS 怎樣排版:
檢視原始碼 CSS
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 | ul, li { margin: 0; padding: 0; list-style: none; } a img { border: none; } #abgne-block-20110406 { margin: 0 auto; width: 632px; /* 框架圖片的寬 */ height: 438px; /* 框架圖片的高 */ position: relative; background: url('images/frame.gif') no-repeat; } #abgne-block-20110406 a.prev, #abgne-block-20110406 a.next { position: absolute; top: 173px; display: block; width: 56px; /* 左右鈕圖片的寬 */ height: 53px; /* 左右鈕圖片的高 */ text-indent: -9999px; } #abgne-block-20110406 .prev { background: url('images/left.png') no-repeat; } #abgne-block-20110406 .next { background: url('images/right.png') no-repeat; right: 0; } #abgne-block-20110406 .slides { overflow: hidden; position: relative; top: 32px; left: 30px; width: 574px; /* 框架中間區塊的寬 */ height: 376px; /* 框架中間區塊的高 */ } #abgne-block-20110406 .slides ul { position: absolute; width: 9990px; height: 100%; } #abgne-block-20110406 .slides li { width: 574px; /* 框架中間區塊的寬 */ height: 100%; float: left; } |
在動手寫程式前先來看看畫面吧~
是不是經過巧手裝飾過後就變的很有質感了呢!接著透過 jQuery 的魔法來完成最後的步驟:
檢視原始碼 JavaScript
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 | $(function(){ // 先取得必要的元素並用 jQuery 包裝 // 再來取得 $block 的寬度及設定動畫時間 var $block = $('#abgne-block-20110406'), $slides = $block.find('.slides'), $ul = $slides.find('ul'), _width = $slides.width(), _left = _width * -1, _animateSpeed = 400; // 先把最後一個 li 的內容插入到第一個 li 前面 // 並設定 $ul 的 left 及 width $ul.find('li:first').before($ul.find('li:last')).end().css({ left: _left, width: _width * ($ul.find('li').length + 1) }); // 當點擊到 a.prev 時 $block.find('a.prev').click(function(){ // 移動 $ul $ul.stop(false, true).animate({'left' : _left + _width}, _animateSpeed, function () { // 把最後一個 li 的內容插入到第一個 li 前面 $ul.find('li:first').before($ul.find('li:last')).end().css('left', _left); }); return false; }); // 當點擊到 a.next 時 $block.find('a.next').click(function(){ // 移動 $ul $ul.stop(false, true).animate({'left' : _left - _width}, _animateSpeed, function () { // 把第一個 li 的內容插入到最後一個 li 後面 $ul.find('li:last').after($ul.find('li:first')).end().css('left', _left); }); return false; }); $block.find('a').focus(function(){ this.blur(); }); }); |
其中比較關鍵的是 .after() 及 .before() 的地方:
檢視原始碼 JavaScript
1 | $ul.find('li:last').after($ul.find('li:first')).end().css('left', _left); |
它會馬上的把第一個 li 的內容再插入到最後一個 li 的後面,也就產生了不間斷的效果。不過一直插入移除 DOM 是會耗一點效能啦!
最後要讓它能自動切換的話,則得再加上計時器功能:
檢視原始碼 JavaScript
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 | $(function(){ // 先取得必要的元素並用 jQuery 包裝 // 再來取得 $block 的寬度及設定動畫時間 var $block = $('#abgne-block-20110406'), $slides = $block.find('.slides'), $ul = $slides.find('ul'), _width = $slides.width(), _left = _width * -1, _animateSpeed = 400, // 加入計時器, 輪播時間及控制開關 timer, _showSpeed = 3000, _stop = false; // 先把最後一個 li 的內容插入到第一個 li 前面 // 並設定 $ul 的 left 及 width $ul.find('li:first').before($ul.find('li:last')).end().css({ left: _left, width: _width * ($ul.find('li').length + 1) }); // 當點擊到 a.prev 時 var $prev = $block.find('a.prev').click(function(){ // 移動 $ul $ul.stop(false, true).animate({'left' : _left + _width}, _animateSpeed, function () { // 把最後一個 li 的內容插入到第一個 li 前面 $ul.find('li:first').before($ul.find('li:last')).end().css('left', _left); // 當移動到正確位置後, 依判斷來啟動計時器 if(!_stop) { clearTimeout(timer); timer = setTimeout(move, _showSpeed); } }); return false; }); // 當點擊到 a.next 時 var $next = $block.find('a.next').click(function(){ // 移動 $ul $ul.stop(false, true).animate({'left' : _left - _width}, _animateSpeed, function () { // 把第一個 li 的內容插入到最後一個 li 後面 $ul.find('li:last').after($ul.find('li:first')).end().css('left', _left); // 當移動到正確位置後, 依判斷來啟動計時器 if(!_stop) { clearTimeout(timer); timer = setTimeout(move, _showSpeed); } }); return false; }); // 如果滑鼠移入 $block 時 $block.hover(function(){ // 關閉開關及計時器 _stop = true; clearTimeout(timer); }, function(){ // 如果滑鼠移出 $block 時 // 開啟開關及計時器 _stop = false; timer = setTimeout(move, _showSpeed); }).find('a').focus(function(){ this.blur(); }); // 計時器使用 function move(){ $next.click(); }; timer = setTimeout(move, _showSpeed); }); |
男丁老師你好:
我照著你網站的說明把這個效果加到網站上
但是發現一個問題....
就是點prev的時候是很順的後面一張接著前面一張
但是點next時似乎不會後面接著前面一張跑
不知道是不是因為只有兩張圖的關係
範例在下面
http://kj.i2w.com.tw/test.asp
勞煩老師幫我看一下囉,謝謝
男丁老師你好
我希望可以此輪播可以通用在不同尺寸的瀏覽器,
自動比例縮放,
請問要怎麼做?
(因為我有用百分比的方式直接改,但是圖會跑掉~.~)
老師您好~
謝謝您提供這麼棒的教學網站,
讓對設計有興趣的朋友,可以更多樣化的呈現自己的網站,
小妹就是透過您的網站,開始嘗試動態的網頁設計,
但初學階段仍有很多不懂的地方,
像是在套用的過程中,發現網站下拉捲軸時,輪播圖會一直跳回最頂端的地方,
造成瀏覽網頁時,一直不受滑鼠控制的跳回頂端orz....
以下是我的作品範例:http://w.mtwebcenters.com.tw/fuyesyuan/_preview/產品介紹.html
想請您抽空看看,請教您該如何修正??
如果需要費用,也請老師報個價,謝謝喔。
我猜想應該是你加了可以點擊超連結回到頂部之類的外掛套件所影響到了!!
可以試著把其它 js 先拿掉試試看!
老師您好,我是第一次來到本站,當然也是第一次開始深入了解JQuery!
對於老師這篇文章小生有個不解之謎呀! 就是問什麼要將最後一個插入到第一個前面呢?
P.S.老師程式碼寫得很棒呢! 今天我多看了幾篇,都很清楚!! 看來以後要常常光顧這一站了!!
因為當使用者在第一張圖片要往左切換顯示時,前面並沒有其它圖片了,所以才需要把最後一張再插入到第一張前面,藉由這樣的方式來產生不間斷的效果。
ok!
小生瞭解了,謝謝老師的講解!!