【初試 jQuery】分析輪播圖的實現原理,手寫輪播圖,代碼細節分析

效果圖

如果想看網頁效果,請點擊該鏈接:http://114.55.219.55:8000/ (該鏈接不保證以後長期有效)

1、從右向左循環滑動

2、可通過左右兩端的箭頭切換圖片(有滑動效果)

3、可底部的小圓圈切換到指定圖片(沒有滑動效果)

4、圖片切換,底部的小圓圈的樣式會自動跟着改變

5、鼠標懸停在上面,會停止自動滑動。移除,會自動恢復自動滑動

前言

食用前必看

1、本博客適用人羣:有css基礎,對jQuery有基本的瞭解(我也是初學jQuery)

2、如果你使用的素材圖大小不一樣,自行修改代碼中的有關地方。這幾張圖片我是從慕課網的首頁扣下來的。在本博客的末尾,我也貼出來,方便各位拷貝下來。

分析

實現這個輪播圖,有一個最關鍵的難點!這裏我分析如何解決這個關鍵點的原理,其他的坑和注意的點以及容易混亂的細節,我都已經在代碼中加上了詳細的註釋。在明白這個“如何解決這個難點”之後,可直接去結合註釋分析代碼。

假設,我們輪播顯示的只有4張圖,這4張圖從右向左滑動。滑動一張圖後,停留一會,再滑動下面一張。

那麼問題是:當前已經顯示的是第4張圖,如何從第4張圖【】回到第1張圖(看起來好像無縫銜接)?注意,這裏是【滑】回,而不是閃現回到第1張的位置。如果是閃現回到第1張的位置,直接通過設置ul的marginLeft即可實現。

我們可以將第1張圖複製一份放到最後(就是說第5張圖是第1張圖的副本)。假設當前正在顯示第4張圖,然後第4張圖滑動到第5張圖。此時第4張圖【滑】回到第1張圖的動畫我們已經看到了,雖然是第1張圖的副本,但是視覺上就像是是:第4張圖【滑】回到第1張圖。此時顯示的是第5張圖(第1張的副本),此時來個【偷樑換柱】,通過設置ul的marginLeft閃回到真正的第1張的位置。由於副本和第1張一模一樣,所以這個【閃回】在視覺上是感受不到的。

如何從第1張【滑】回到第4張呢?

在上面分析了:如何從第4張滑回到第1張,那麼“如何從第1張【滑】回到第4張”的道理也是一樣的。

假設當前顯示的就是第1張,我點擊了左端的 “<”。此時來個【偷樑換柱】,通過設置ul的marginLeft一瞬間切換到第5張圖(第1張的副本),由於副本和第1張一模一樣,所以這個閃現在視覺上是感受不到的。那麼再從第1張的副本滑動第4張。那麼在視覺上就好像是第1張【滑】回到第4張的假象了。

明白這個原理,就已經成功了一半。剩下就是代碼實現,但是這個代碼的不少細節都要考慮的比較【細緻】,大家可以多多嘗試。

代碼

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>輪播圖 by passerbyYSQ</title>
<script src="js/jQuery1.4.2.js"></script>

<!-- coded by passerbyYSQ -->

<style>
	* {
		margin: 0px;
		padding: 0px;
		list-style: none;
	}
	#banner {
		width: 936px; /* 剛好爲圖片真實寬度的一半 */
		height: 382px; /* 剛好爲圖片真實高度的一半 */
		margin: 50px auto;
		border-radius: 20px;
		overflow: hidden;
		/* border: 1px #000 solid; */ /* 加上邊框便於觀察 */
		position: relative;
	}
	#banner #bg img {
		width: 936px; /* 圖片高度也等比縮小 */
	}
	#banner li {
		float: left;
	}
	#banner #aList li {
		width: 20px;
		height: 20px;
		border-radius: 10px;
		background: rgba(0, 0, 0, 0.5);
		float: left;
		margin: 0px 5px;
	}
	#banner #aList li:hover {
		cursor: pointer;
	}
	#banner #aList {
		position: absolute;
		bottom: 10px;
		left: 50%;
		/* margin-left: -60px; */
	}
	
	#banner .left, #banner .right {
		width: 50px;
		height: 50px;
		border-radius: 25px;
		background: rgba(0, 0, 0, 0.2);
		position: absolute;
		top: 50%;
		margin-top: -25px;
		font-size: 35px;
		font-family: bold;
		color: rgba(255, 255, 255, 0.8);
		text-align: center;
		line-height: 45px;
	}
	#banner .left:hover, #banner .right:hover {
		background: rgba(0, 0, 0, 0.5);
		cursor: pointer;
	}
	#banner .left {
		left: 20px;
	}
	#banner .right {
		right: 20px;
	}
</style>
<script>
	$(function() {				
		// 將#banner #bg中的第一個li複製一份, 放到#banner #bg的最後
		$firstLiCopy = $("#banner #bg li:first").clone(true);
		$("#banner #bg").append($firstLiCopy);
	
		var imgWidth = 936;
		var imgCount = $("#banner #bg li").length;  // 此時, imgCount = 5, 但是實際上我們循環顯示的只有4張
		// 爲了便於區分說明, 我們聲明: 第1張圖片爲【真正的第1張圖片】, 第5張圖片爲【真正的最後1張圖片】
		
		// 動態設置#banner #bg的寬度
		$("#banner #bg").css("width", imgWidth * imgCount);
		// 有多少張圖片, 底部就有多個小圓圈
		for (var i = 0; i < imgCount - 1; i++) { // i = 0, 1, 2, 3 < 4
			$("#banner #aList").append($("<li></li>"));
		}
		// 動態糾正#banner #aList, 使其水平居中
		$("#banner #aList").css("marginLeft", - $("#banner #aList").width() / 2);
		
		// 底部小圓圈選中時的樣式
		var aSelectedCss = {
						background: "rgba(255, 255, 255, 0.5)",
						width: 30
					};
		// 底部小圓圈未選中時的樣式
		var aNoneCss = {
						background: "rgba(0, 0, 0, 0.5)",
						width: 20
					};
		
		// 一開始進來頁面, 將底部的第一個小圓圈設置爲選中的樣式
		$("#banner #aList li").eq(0).css(aSelectedCss);
		
		var stayDuration = 2000; 
		var slideDuration = 500; // 一張圖片滑動所需的時間
		var curIndex = 0; // 當前的顯示的圖片的索引(從0開始)
		
		// 根絕curIndex的變化, 動態設置底部那一排小圓圈的樣式變化
		// 在slide方法中被調用
		function setA() {
			// 類推一下。 當第1張圖片滑動到第2張圖片完成後, 此時curIndex = 1
			// 當第4張圖片滑動到第5張圖片完成後, 換言之此時剛剛開始顯示第5張(第1張的副本), 那麼此時的curIndex爲多少?
			// 所以那麼此時curIndex == imgCount - 1 == 4
			if (curIndex == imgCount - 1) {
				$("#banner #aList li").eq(0).css(aSelectedCss);
				$("#banner #aList li").eq(0).siblings().css(aNoneCss);
				return;
			}
			// 在這裏是否需要考慮curIndex < 0的情況? 
			// 不需要!!!
			
			$curA = $("#banner #aList li").eq(curIndex);
			$curA.css(aSelectedCss);
			$curA.siblings().css(aNoneCss);
		}
		
		// 滑動一張圖片
		function slide(isToLeft) { // ifToLeft = true : 表示從右向左滑動
			if (isToLeft) {
				curIndex++;
				// 如果curIndex == 2, 說明第1張圖片剛剛滑過去, 現在正在顯示第2張圖片
				// 以此類推
				// 如果curIndex == 5, 說明第4張圖片剛剛滑過去, 現在正在顯示第5張圖片(第5張圖片是第一張圖片的副本)
				if (curIndex >= imgCount) {
					// 此時偷樑換柱, 一瞬間將位置瞬移到真正的第1張圖片
					curIndex = 1; // 第一張已經完成滑過動畫了
					$("#banner #bg").css("marginLeft", 0);	
				}
				
				$("#banner #bg").stop().animate({
					//marginLeft: "-=" + imgWidth // 不能使用這個, 否則當連續快速點擊"<"會有bug
					marginLeft: - curIndex * imgWidth
				}, slideDuration, function() {
					setA();
				})
			} else {
				curIndex--;
				// 如果curIndex == -1, 說明下面需要執行的動畫就是: 【真正的第1張圖片】滑動到【真正的最後1張圖片】
				// 不過在此之前, 先偷樑換柱, 將位置瞬移到第5張(第1張的副本)的位置
				if (curIndex < 0) { 
					curIndex = imgCount - 2;  // curIndex = 3
					$("#banner #bg").css("marginLeft", - imgWidth * (imgCount-1));
				}
				
				$("#banner #bg").stop().animate({
					//marginLeft: "+=" + imgWidth // 不能使用這個, 否則當連續快速點擊">"會有bug
					marginLeft: - curIndex * imgWidth
				}, slideDuration, function() {
					// if (curIndex == -1) 裏面已經將curIndex重置爲3, 所以在setA裏面不要考慮curIndex < 0的情況
					setA();
				})
			}
		}
		
		var timer = null;
		// 開啓自動滑動
		function autoPlay() {
			timer = setInterval(function() { // 這裏給timer賦值了!!!
				slide(true); // 從右向左滑動
			}, stayDuration); // 先等待再執行
		}
		autoPlay(); // 一進頁面, 輪播圖自動滑動起來
		
		$("#banner").hover(function() {
			clearInterval(timer); // 鼠標懸停在輪播圖(即#banner)時, 清除定時器timer
		}, function() {
			autoPlay(); // 鼠標移出時, 再開一個定時器
		});
		
		// 我們通過底部的小圓圈和左右的"<"和">"來切換圖片的時候, 是否會影響和混亂輪播圖的自動循環滑動?
		// 不會!! 因爲鼠標懸停在輪播圖的時候, 我們已經將定時器timer的清除掉了
		$("#banner #aList li").click(function() {
			$(this).css(aSelectedCss);
			$(this).siblings().css(aNoneCss);
			
			curIndex = $(this).index();
			$("#banner #bg").css("marginLeft", - imgWidth * curIndex);
		});
		
		$("#banner .left").click(function() {
			slide(false);
		});
		$("#banner .right").click(function() {
			slide(true);
		});
	});
</script>
</head>
	<body>

			<div id="banner">
				<ul id="bg">
					<li><img src="img/1.jpg"/></li>
					<li><img src="img/2.jpg"/></li>
					<li><img src="img/3.jpg"/></li>
					<li><img src="img/4.jpg"/></li>
				</ul>
				<ul id="aList">
					<!-- <li><a href="#"></a></li>
					<li><a href="#"></a></li>
					<li><a href="#"></a></li>
					<li><a href="#"></a></li> -->
				</ul>
				<div class="left">&lt</div>
				<div class="right">&gt</div>
			</div>
		
	</body>
</html>

素材圖:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章