效果圖
如果想看網頁效果,請點擊該鏈接: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"><</div>
<div class="right">></div>
</div>
</body>
</html>