1. 程式人生 > >jQuery實現類似淘寶輪播圖

jQuery實現類似淘寶輪播圖

jQuery實現類似淘寶輪播圖

本週的作業是寫一個類似淘寶首頁的jQuery輪播圖,這裡做出記錄。

如有錯誤,歡迎批評指證。

html實現靜態的佈局

靜態佈局分析

一個輪播圖靜態的部分分為三個

  • 展示區
  • 圖片的儲存部分
  • 左右按鈕
  • 下方小圓點作為提示部分

html部分程式碼

	<div class="container"> <!-- 展示區 -->
		<div class="photoContainer">
			<img src="img/3.jpg" alt="3" >
			<
img src="img/1.jpg" alt="1" > <img src="img/2.jpg" alt="2" > <img src="img/3.jpg" alt="3" > <img src="img/1.jpg" alt="1" > </div> <ul class="dots"> <!-- 三個小按鈕 --> <li class="dot"></li> <li class="dot"></li> <li class="dot"
></li> </ul> <div class="left-triangle"> <!-- 向左的箭頭 --> <img src="img/left_arrow.png" id="left"> </div> <div class="right-triangle"> <!-- 向右的箭頭 --> <img src="img/left_arrow.png" id="right"> </div> </div>

css部分

  • 設定展示區 container的樣式
.container{
	width: 600px; 
	height: 400px; /*寬和高可以自己設定*/
	background: black;
	margin:20px auto;
	overflow: hidden; 
	position: relative;
}

利用overflow屬性將超出展示區的部分隱藏

圖片的容器依靠展示區的容器定位 設定position屬性

  • 設定圖片的容器 和 圖片
.photoContainer{
	position: absolute;
	left: -600px;
	display: inline-block;
	white-space: nowrap;
}
.photoContainer img{
	width: 600px;
	height: 400px; /*和展示區的長寬設定為一樣的*/
	margin: 0;
	padding: 0;
	display: inline-block;
}

  • 左右箭頭的設定
.left-triangle{
	position: absolute;
	top: 50%;
	left: 0;
	margin-top:-27.2px;
	margin-left:-37px;
	transition: margin-left 1s;
	cursor: pointer;
}
.right-triangle{
	position: absolute;
	top: 50%;
	right: 0;
	margin-top:-27.2px;
	margin-right:-37px;
	transition: margin-right 1s;
	cursor: pointer;
}
#right{
	transform: rotate(180deg); /*順時針旋轉180°*/
}

  • 小圓點部分
.dots{
	width: inherit;/*獲取父元素的相應值*/
	position: absolute;
	bottom: 10px;
	text-align: center;
}
.dot{
	display: inline-block;
	width: 20px;
	height: 20px;
	border-radius: 50%;
	background: white;
	margin-right: 20px;
	cursor: pointer;
}
.redDot{
	background: red;
}

其中的.redDot是高亮顯示的樣式


  • 設定部分動畫 讓左右箭頭的出現和消失
/*暫時css確定滑鼠移動到 出現左右小圖示*/
.container:hover .left-triangle{
	margin-left:0;
}
.container:hover .right-triangle{
	margin-right:0;
}

jQuery 邏輯部分

功能分析

  • 自動迴圈播放
  • 點選箭頭實現圖片替換
  • 滑鼠放入容器內迴圈停止
  • 滑鼠移開容器 迴圈繼續
  • 下方原點根據圖片響應的滾動 並且點選可以移動到相應的圖片

功能實現

1)自動迴圈播放

這個部分的難點在於:

  • 第一張和最後一張如何無縫的銜接。
  • 如何實現迴圈播放

對於第一個問題:

一個小技巧就是在要展示的圖片的第一張前面放最後一張

最後一張圖片的後面放上第一張圖片

程式碼如下:

<div class="photoContainer">
    <img src="img/3.jpg" alt="3" >
    <img src="img/1.jpg" alt="1" >
    <img src="img/2.jpg" alt="2" >
    <img src="img/3.jpg" alt="3" >
    <img src="img/1.jpg" alt="1" >
</div>

第二個問題:

  1. 使用定時器
  • setInterval()方法會重複呼叫一個函式或執行一個程式碼段,在每次呼叫之間具有固定的時間延遲,返回一個intervalID,可以作為引數傳給clearInterval()來取消該定時器。
  1. 利用圖片容器的寬度,不斷移動left的定位,就可以讓圖片每次在展示區顯示一次
  2. 使用animate屬性讓圖片有拖動的效果

解決的了以上兩個問題就可以寫定時器部分

	//預設第一個小圓點是亮的
	$(".dots").children("li").eq(0).addClass("redDot");

	//獲取圖片的寬度
	var imgWidth = $(".photoContainer").children('img').eq(0).width();

	//獲取原點的數量
	var length = $(".dots").children('li').length;
//設定定時器的變數
	var time;
function run(){
	clearInterval(time); //清除迭代器防止鬼畜
	time = setInterval(function(){
		//亮小圓點
		$(".dots").children('li').each(function(){
			//如果是當前圖片
			if($(this).hasClass("redDot")){
				num = $(this).index()+ 1;
			//圖片移動
				$(".photoContainer").animate({
					//去掉收尾用於銜接的圖片的寬度
					left :-num*imgWidth - imgWidth + "px"
				},800);
				//到達最後一張,從頭開始
				if(num == length){
					$(".photoContainer").animate({
						left:-imgWidth+"px"
					},0);
					num = 0;
				}
			}
		});
			//改變相應小圓點的樣式
			$(".dots").children('li').eq(num).addClass("redDot");
			//移除其他小點的樣式
	$(".dots").children('li').eq(num).siblings("li").removeClass('redDot');
		},2000);
	}

注意:

  • 此處是根據遍歷小圓點的樣式來判斷當前是哪一個圖片,避免全域性變數統計。以便實現之後的功能
  • 使用定時器之前一定要清除定時器。不然多次點選之後就會出現非常鬼畜的速度。

2) 滑鼠移入和移除實現停止和繼續移動

給容器新增相應的清除和建立定時器事件就可以實現:

		//滑鼠移動到視窗內
	$(".container").mousemove(function(event) {
		clearInterval(time);
	});
//移出視窗內
	$(".container").mouseout(function(event) {
		run();
	});

3)點選左邊箭頭向左移動

難點:第一張圖片移動到最後一張圖片

可以通過在第一張圖片的dom結構之前加最後一張圖片,直接用animate屬性向左移動,時間為0.多新增的圖片就作為鋪墊效果。實現無縫連結

//當達到最左邊的時候
if(flag < 0){
flag = length-1;
$(".photoContainer").animate({left: -flag * imgWidth - imgWidth+"px"}, 0);
}

整體程式碼

	$(".left-triangle").click(function(event) {
		var flag; 
		//判斷當前在哪一個照片
		$(".dots").children('li').each(function(){
			//將圖片容器向右移動
			if($(this).hasClass('redDot')){
				flag = $(this).index() - 1;
					$(".photoContainer").animate({left: -flag * imgWidth - imgWidth+"px"}, 300);
				//當達到最左邊的時候
				if(flag < 0){
					flag = length-1;
					$(".photoContainer").animate({left: -flag * imgWidth - imgWidth+"px"}, 0);
				}

			}
		});
		//圖示按鈕改變
		$(".dots").children('li').eq(flag).addClass('redDot');
		$(".dots").children('li').eq(flag).siblings('li').removeClass('redDot');
	});

4) 點選右邊箭頭向右移動

與左邊箭頭類似 只需在最後一張後面新增第一張圖片,同時annimate時間設定為0.

//右邊按鈕新增事件
	$(".right-triangle").click(function(event) {
		var flag ;//判斷當前在哪一個照片
		$(".dots").children('li').each(function(){
			//將圖片容器向左移動
			if($(this).hasClass('redDot')){
				flag = $(this).index() + 1;
				console.log(flag);
				$(".photoContainer").animate({left: -flag * imgWidth - imgWidth +"px"}, 300);
				//當達到最右邊的時候 回到最左邊
				if(flag == length){
					flag = 0;
					$(".photoContainer").animate({left: -imgWidth + "px"}, 0);
				}
			}
		});
		//圖示按鈕改變
		$(".dots").children('li').eq(flag).addClass('redDot');
		$(".dots").children('li').eq(flag).siblings('li').removeClass('redDot');
	});

5) 點選圓點切換圖片

利用事件委託 給父元素新增事件。判斷當前圖片並進行移動。

//給小點新增事件 事件委託
	$(".dots").on("click","li",function(event) {
		$(this).addClass('redDot');
		$(this).siblings('li').removeClass('redDot');
		//獲取當前序號
		var flag = $(this).index();
		$(".photoContainer").animate({
			left: -flag*imgWidth - imgWidth + "px"},
			300);
	});