jQuery實現類似淘寶輪播圖
阿新 • • 發佈:2018-11-25
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>
第二個問題:
- 使用定時器
setInterval()
方法會重複呼叫一個函式或執行一個程式碼段,在每次呼叫之間具有固定的時間延遲,返回一個intervalID
,可以作為引數傳給clearInterval()
來取消該定時器。
- 利用圖片容器的寬度,不斷移動left的定位,就可以讓圖片每次在展示區顯示一次
- 使用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);
});