天天看點

JQuery無縫輪播

前言:輪播圖是前端很普通很常見的一種網頁動效,很多架構或插件都封裝了輪播圖元件供我們使用,例如Bootstrap,layui,swiper等架構都有輪播圖元件,并且也是比較好用的。但往往我們需要做的輪播圖并非完全中規中矩的,或許有些另類,此時架構可能就無法滿足我們另類的需求了,需要自己寫輪播。一直以來也很少自己寫,我個人喜歡使用swiper插件,但本次遇到了一個比較另類的輪播,是以自己寫了一個無縫輪播,将輪播圖設計思路邏輯簡單記錄于此。

首先是基礎網頁布局,布局方面不多講,很基礎,主要分3塊:輪播圖塊,訓示器塊,左右切換按鈕塊。直接上代碼:

<div id="bgblock">
		<ul class="carousel">
			<li class="carousel_item">
				<img src="image/1.jpg" />
			</li>
			<li class="carousel_item">
				<img src="image/2.jpg" />
			</li>
			<li class="carousel_item">
				<img src="image/3.jpg" />
			</li>
			<li class="carousel_item">
				<img src="image/4.jpg" />
			</li>
			<li class="carousel_item">
				<img src="image/5.jpg" />
			</li>
		</ul>
		<ul class="pointer">
			<li class="pointer_item pointer_item_active">1</li>
			<li class="pointer_item">2</li>
			<li class="pointer_item">3</li>
			<li class="pointer_item">4</li>
			<li class="pointer_item">5</li>
		</ul>
		<div class="carousel_btn carousel_btn_left"></div>
		<div class="carousel_btn carousel_btn_right"></div>
	</div>
           

其次是css,整體來講也十分基礎,其中有三點需要注意:輪播圖父容器需要設定定位屬性,因為輪播滾動主要依賴于定位後的left屬性來控制。具體輪播圖li需進行浮動,輪播圖父容器需設定overflow:hidden屬性,用來隐藏超出的其他輪播圖。

*{
	padding: 0;
	margin: 0;
}
#bgblock{
	width: 960PX;
	height: 400px;
	margin: 0 auto;
	position: relative;
	overflow: hidden;
}
.carousel{
	width: 960px;
	height: 400px;
	position: absolute;
	left: 0;
	top: 0;
	overflow: hidden;
}
.carousel_item{
	float: left;
	width: 960px;
	height: 400px;
	list-style-type: none;
}
.carousel_item>img{
	width: 960px;
	height: 400px;
}
.pointer{
	width: 225px;
	height: 50px;
	border-radius: 25px;
	position: absolute;
	bottom: 10px;
	left: 50%;
	margin-left: -150px;
}
.pointer_item{
	width: 30px;
	height: 30px;
	list-style-type: none;
	float: left;
	margin-top: 10px;
	margin-left: 15px;
	text-align: center;
	line-height: 30px;
	cursor: pointer;
	border-radius: 15px;
	background-color:#ffffff;
}
.pointer_item_active{
	color: #FFFFFF;
	background: #31c27c;
}
.carousel_btn{
	width: 50px;
	height: 48px;
	cursor: pointer;
	position: absolute;
	top: 50%;
	margin-top: -24px;
	background-repeat: no-repeat;
}
.carousel_btn_left{
	left: 0;
	background-image: url(../image/聚合次元左按鈕.png);
}
.carousel_btn_right{
	right: 0;
	background-image: url(../image/聚合次元右按鈕.png);
}
           

重點來了,js輪播邏輯:在此使用了JQuery庫簡化dom操作,無論是js或是jq功能邏輯都一樣,差別隻是具體dom操作或方法的寫法而已。如何實作輪播?

首先需要思考輪播圖都有哪些功能?1:點選左右切換按鈕,向上或向下翻頁。2:訓示器訓示目前輪播位置,其次點選訓示器可直接輪播至該輪播頁。3:自動進行輪播。将功能細化後要做什麼就十厘清楚了。第一步當然是擷取可能用到的dom元素,将其綁定在一個變量上友善我們後面操作。其次我們需要定義兩個非常重要的變量:autoplay(是否自動播放),nowIndex(訓示器位置,或者說輪播位置)。

var carousel=$(".carousel"),//輪播圖
		carouselItem=$(".carousel_item"),//輪播圖item
		carouselItemWidth=carouselItem.eq(0).width(),//一個img的寬度
		pointer_item=$(".pointer_item"),//訓示器
		btnLeft=$(".carousel_btn_left"),//左按鈕
		btnRight=$(".carousel_btn_right");//右按鈕
var nowIndex=0,
	autoplay=true;
           

第二步,實作點選左右切換按鈕,輪播圖輪播至下一張功能。如何實作?左側按鈕點選後,會切換至上一張圖,是以nowindex應該--。右側按鈕點選後,會切換至下一張圖是以nowindex應該++。如何讓其切換,上面在css部分已經說過了,主要是通過定位後的left屬性來進行控制。第一張img的left就應該為0,第二張為-1個li的寬度,第3張為-2個li的寬度...最後1張為-要輪播的圖的張數-1。若通過直接改變left值會發現并沒有滾動效果而至直接切換,若想要img滾動切換效果額采用jq的動畫animate()方法實作。完成上述步驟後運作會發現一個問題第一張時點選左側按鈕和最後一張點選右側按鈕時nowindex為-1或6,輪播位置空白。此時就需要進行條件判斷,限定nowindex保證其正常。具體為:當nowindex<0時,讓其等于輪播img數量-1,nowindex>輪播數量-1

時讓其等于0。

第三步:自動播放,想要自動播放其實隻需添加一個定時器:setInterval,設定間隔時間,每隔多少秒執行一次。仔細想想自動播放其實就是自己不斷地播放下一張,也就是執行右側(下一張)按鈕的click事件。自動播放後測試時又發現一個小問題:剛剛點選左右按鈕後,切換了一張,然後定時器時間到了又自動切換了一次,這樣使得使用者體驗很差。是以我們需要利用autoplay變量幫助我們關閉開啟自動播放。當使用者滑鼠懸停在左右按鈕上時,代表使用者想要手動切換,是以我們應該設定關閉自動輪播,當使用者滑鼠離開這兩按鈕開啟輪播。實作開啟關閉輪播可以通過開啟關閉定時器來實作,但相對麻煩在此選擇利用autoplay變量,在定時器中判斷變量值,為true則執行輪播代碼,否則不執行即可。

第四步:做到此其實已經實作了整個輪播,可以正常輪播了,但是會有一個小缺陷:即在第一張向上,最後一張向下時切換會有“縫隙”,具體不是很好描述,做完上面的步驟測試就會明白。如何讓其無縫滾動呢?無縫滾動的思路就是:将第一個img複制一份添加至父元素最後,當其為第一張向上時直接切換至至複制的這張(也就是現在的第6張),然後再滾動至上一張(第5張,以前的最後一張),最後一張向下:切換至第6張(複制的那張)再滾動至第一張,這樣肉眼其實看不到切換這個步驟,是以就是無縫輪播。整個代碼如下:

carousel.append(carouselItem.eq(0).clone());
	carouselItem=$(".carousel_item");
	carousel.width(carouselItem.length*960);
	//左切換按鈕事件
	btnLeft.click(function(){
		nowIndex--;
		imgTransfrom(nowIndex);
	})
	//右切換按鈕事件
	btnRight.click(function(){
		nowIndex++;
		imgTransfrom(nowIndex);
	})
	//訓示器切換事件
	pointer_item.click(function(){
		var index=$(this).index();
		imgTransfrom(index);
	})
	//滑鼠懸停自動播放停止事件
	$(".carousel_btn_left,.carousel_btn_right").hover(function(){
		autoplay=false;
	},function(){
		autoplay=true;
	})
	//自動播放
	setInterval(function(){
		if(autoplay){
			btnRight.click();
		}	
	},3000)
	
	function imgTransfrom(index){	
		if(index<0){
			index=carouselItem.length-2;
			carousel.css("left",-(carouselItem.length-1)*carouselItemWidth);
		}
		if(index>carouselItem.length-1){
			index=1;
			carousel.css("left",0);
		}
		nowIndex=index;
		console.log("index:"+nowIndex);
		carousel.animate({
			left:-index*carouselItemWidth
		},500)
		if(index==carouselItem.length-1){
			pointer_item.eq(0).addClass("pointer_item_active");
			pointer_item.eq(0).siblings().removeClass("pointer_item_active");
		}else{
			pointer_item.eq(index).addClass("pointer_item_active");
			pointer_item.eq(index).siblings().removeClass("pointer_item_active");
		}
	}
           

至此,簡單的無縫輪播就徹底完成了!在此舉例寫的這個輪播實際上是個很正常的輪播,并非開頭所說另類輪播,無論是另類或是正常它的原理,邏輯都是一樣的,該學習的是思維,原理,而非具體的寫法。