Home » jQuery 應用

[jQ]用 jQuery 做畫廊 – 左右不間斷的商品展示輪播

範例 1
範例 2
沒錯!只要 1,200 元就能獲得我們團隊完整的協助,讓效果能迅速的整合到您的網站,並保證瀏覽器的相容性。
立刻申請!

一般 Flash 廣告或是商品的輪播大多是不間斷的,所以就常會有網友問說 jQuery 的範例是否能做到不間斷的輪播呢?答案其實連想都不用想的也知道是可以的,且要達到同樣效果的方法有好幾種,筆者此次就針對一種較簡單但效能會差一點點的方式來介紹。

首先當然是要準備好 HTML(圖片還是一樣從梅干那邊 A 來的):

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">&lt;</a>
		<a href="#" class="next">&gt;</a>
    </div>
</body>

這次的範例會多加一個外框,因此就會看到有多出一層來包裹 ul。接著就來看 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);
});
範例 1 範例 2

檔案描述
基本的範例檔案(免空) 開始下載
基本的範例檔案 會員限定

46 筆針對 [jQ]用 jQuery 做畫廊 – 左右不間斷的商品展示輪播 的迴響

  1. 男丁格爾老師您好:

    點了左右後範例會連續跳兩張,需要調整哪個參數,才可以讓他不會跳著播放呢??謝謝老師的解答 ^^

  2. 請問老師:
    如果還要加上 [jQ]用 jQuery 做廣告 – 左右水平廣告輪播 這篇裡面的圓點選單要怎麼寫呢?

    • 原理基本上是一樣的, 只是我現在顯示的寬度是配合圖片的寬度
      你可以試著修改移動時的寬度就可以了

  3. (關於lazyload)
      男丁老師,不好意思 請教您一個問題喔, 我正在設計的網站 有非常大量的圖片(粗略估計200-300張,約350MB), 網站呈現圖片的方式就像這篇教的畫廊一樣, 每個畫廊都是由click某個class 然後顯現出來的。
     
      圖片非常大量, 每次載入都需要滿多時間, 所以試著用lazyload的方式(event:"click")延遲載入圖片, 網頁開啟的時間明顯變快了, 但問題是 每次開啟一個div畫廊, 就要click一下才跑出一張圖片, 然後按">"下一張, 下一張還是要在click一下才顯現出來。
     
      我希望的方式是, 每次開啟一個div畫廊, 就觸發整個div的圖片下載, 有兩個地方需要解決, 第一就是觸發載入圖片的方式要改成$(".something").click(function(){的方式; 第二就是一次要載入整個div的圖片, 不是只有一張。
      
      這個問題對我來說真的很棘手, 剛開始學網頁設計一個多月, 因為實習的關係自己才有這個學習的機會, 但爬文總找不到解決的方法, 懇請男丁老師解答, 謝謝!

    • 你可以找像是 preload 的外掛套件, 當你點了某個畫廊時, 就把該畫廊中的 img 都用 preload 的方式來預載!
      先試看看~因為沒有你的範例, 所以無法給你很明確的 code..

      • 男丁老師, 我試著嘗試你說的preload, 我的js是這樣
        ;(function($){$.preload=function(){var tmp=[],i=arguments.length;for(;i-;)tmp.push($(").attr('src',arguments[i]));};})(jQuery);

        /——————————-/
        但是我還沒用$.preload('/img/space.gif'); 來呼叫圖片, 當打開網頁時就全部下載了, 不是應該等我用$.preload之後, 才會下載圖片嗎?

        懇請老師解答,謝謝

        • 唔, 因為你把圖片的語法都寫在 html 上, 所以頁面載入時就自動下載了
          我沒有那麼多圖片可以測試, 不過也許你的圖片語法不要直接寫在網頁中, 可以利用 preload 後再加入

  4. 老師,我的問題童之前樓上問過的:這個範例一次只出現一張圖
    那如果一次要出現6張圖 然後每次移動只移一張的話 那要怎麼改呢

    但是我修改後圖片跳轉的寬度沒有問題了,但畫面顯示的圖片數始終只有一張,沒辦法排列出其他圖片
    還請幫幫我,謝謝

  5. 你好啊男丁老師, 我發現了有一個bug, 當相片少於3張便會出現問題, 如果只有兩張的話, 會因為只能走出兩張圖而斷了, 另外如果只有一張的, 會什麼都走不出來。因為我有後台, 所以在煩惱如個修改。

    • 唔, 因為這範例是用搬移的方式來做出不間斷的效果, 若要能不限圖片數也有效果的話, 則要改改方式才行哩~

  6. 大大 你好:
    想請教一下這個特效有支援觸控的嗎?就是手機和平板上可使用
    自己有在寫網頁有小小研究 感恩~

    • 暫時還不支援, 接下來 2-3 月時會重新用最新版的 jQuery 來改寫範例, 到時候進階範例的部份都會加上 touch 的功能

發表迴響