寫在前面
是的,這個輪播圖我看了一天的時間,網上找說明,外加請教別人,自己動手試着寫寫,昨天看了一下午,夜裏又簡單想了一下整個流程。終於今天上午開始動手寫,磕磕絆絆,跌跌撞撞,完整的輪播讓我給實現了。
總的來說,算是完成了,爲啥要說算是呢,因爲自己在獨立地寫的過程中還是會出現一些問題,就會看別人怎麼寫的,怎麼實現的,再去對比一下自己的思路。遇到問題,思考問題,再到解決問題,是個需要不斷重複的過程,只有這樣,纔會讓自己熟練,時間長了,再遇到問題知道如何解決,從哪些地方去檢查。
emmmmmmm,簡單的學習心得分享完畢,開始擼思路,擼代碼吧。
輪播圖
輪播圖功能需求:
1. 鼠標經過/離開輪播圖時 左右按鈕的顯示/隱藏
2. 點擊圓點時,圓度變爲當前狀態;圖片切換
3. 左右按鈕點擊時,輪播圖片
4. 圖片輪播時 下方的圓點也跟着切換
5. 鼠標放上焦點圖時 圖片停止自動輪播 ; 鼠標離開時 圖片自動輪播
需要注意的是,頁面一開始圖片就是輪播着的
優化的地方:
1. 增加節流閥:
當連續點擊按鈕時,一張圖片沒有輪播完就會出現下一張。增加的節流閥的目的就是解決上面所敘述的問題。一般節流閥就是兩種操作,關閉節流閥(鎖函數),打開節流閥(開函數)。
2. 提取代碼相同的部分,單獨作爲一個函數,進行調用。還有就是把一些簡單的if語句的判斷可以使用三元表達式來代替
無縫輪播的思想
無縫輪播的佈局:把放輪播圖的ul中的第一個孩子li,複製一份放到ul的最後。
輪播具體實現的過程:正常的話,用戶點擊按鈕進行圖片的輪播,當用戶看到最後一張圖片(其實是我們佈局中的倒數第二張)時,點擊右側按鈕的時候,用戶看到的是第一張圖片,其本質是用戶看到了我們佈局中的最後一張,因爲這一張圖是我們複製的第一張圖,與此同時,我們悄悄的把ul瞬間回到原位置(left = 0),製造假象,讓用戶以爲是第一張圖片,其實是我們佈局中的最後一張。當用戶再點擊時,因爲此時ul已經瞬間移回到原來的位置,再點擊向右輪播的按鈕,ul就按照正常的輪播到第二張圖片。這樣就實現了無縫輪播。
這是輪播圖中比較重要的一個思想。思路解決了 ,咱們就看代碼吧。
代碼裏面有很詳細的解釋,可以認真看看的。
JS部分
// 輪播圖的需求:
// 1. 鼠標經過/離開輪播圖時 左右按鈕的顯示/隱藏
// 2. 點擊圓點時,圓度變爲當前狀態;圖片切換
// 3. 左右按鈕點擊時,輪播圖片
// 4. 圖片輪播時 下方的圓點也跟着切換
// 5. 鼠標放上焦點圖時 圖片停止自動輪播 ; 鼠標離開時 圖片自動輪播
// 需要注意的是,頁面一開始圖片就是輪播着的
window.addEventListener('load', function () {
// 1. 鼠標經過輪播圖時 按鈕的顯示和隱藏
// 獲取事件源
var focus = document.querySelector('.focus');
var arrowL = document.querySelector('.arrow-l');
var arrowR = document.querySelector('.arrow-r');
var ol = document.querySelector('.circle');
var ul = focus.querySelector('ul');
var focusWidth = focus.offsetWidth;
focus.addEventListener('mouseenter', function () {
arrowL.style.display = 'block';
arrowR.style.display = 'block';
clearInterval(carousel);
carousel = null;
})
focus.addEventListener('mouseleave', function () {
arrowL.style.display = 'none';
arrowR.style.display = 'none';
// 鼠標離開 自動輪播
carousel = setInterval(function () {
arrowR.click();
}, 3000)
})
// 2.點擊圓點部分
// 圓點的個數應該是與圖片的個數是一致的,所以 應該根據ul中的li的個數動態創建圓點的個數
// js需要寫的具有一定的動態性 改變結構 時 js可以動態生成
for (var i = 0; i < ul.children.length; i++) {
// (1)創建圓點
var li = document.createElement('li');
// (2)添加到ol中
ol.appendChild(li);
// 設置一個變量 用來記錄當前圓點的索引號 後面與圖片位置對應顯示
li.setAttribute('index', i);
// (3).點擊圓點的事件效果 應該在創建之後就綁定事件
li.addEventListener('click', function () {
// (4).被點擊的圓點 變成當前狀態
// 幹掉所有人 ol.children.length所有小圓點的個數
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
// 留下我自己 當前點擊的圓點
this.className = 'current';
// (5). 點擊時圖片輪播
// 獲得當前圓點的索引號
var currentIndex = this.getAttribute('index');
// 輪播到哪個li 把當前圖片對應的圓點的索引號 給點擊的次數
// 是保持圓點 按鈕點擊次數 圖片對應一致
clickCount = currentIndex;
circleMove = currentIndex;
// ul移動的距離 圓點索引號*焦點圖的寬度
animate(ul, -currentIndex * focusWidth);
})
}
// 默認設置第一個圓點爲當前
ol.children[0].className = 'current';
// 無縫輪播:把ul中的圖片複製一份到ul的最後。當用戶點擊到最後一張,就是我們的倒數第二張
// 用戶再點擊時 看到的是第一張的圖片 其實是我們複製了第一張到ul的最後,所以用戶看到的實際上是我們複製的那一張圖
// 這時當用戶再點擊時 我們迅速把ul移回原位left=0,從頭開始 再按照正常的輪播到第二張
// 克隆節點在創建小圓點的後面 因爲克隆出來的節點不需要小圓點
// 複製ul第一個li放到最後 ul.children[0].cloneNode(true)深拷貝
var firstImg = ul.children[0].cloneNode(true);
ul.appendChild(firstImg);
// 點擊按鈕事件
// 點擊右側按鈕 圖片向左輪播 點擊一次 圖片(ul)移動一個圖片的距離
// ul移動的距離 = 點擊次數*焦點圖的寬度 與上面點小圓點的效果類似
// 設置一個變量記錄 點擊的次數 點擊一次圖片滾動一次
var clickCount = 0;
// 記錄圓點的位置 控制圓點的播放
var circleMove = 0;
// 節流閾值:爲了防止點擊過快圖片沒有輪播完就結束的情況
var flag = true;
// 3.右側按鈕點擊
arrowR.addEventListener('click', function () {
if (flag) {
// 先鎖住函數 當動畫執行完畢之後 再解鎖
flag = false; // 關閉節流閥
// (1) 當ul走到最後 我們複製的那一張圖片時:ul的left = 0;迅速復原ul
if (clickCount == ul.children.length - 1) {
ul.style.left = 0;
clickCount = 0; // 點擊置0
}
clickCount++;
animate(ul, -clickCount * focusWidth, function () {
flag = true; // 打開節流閥
});
// (2) 圖片輪播時 圓點也在變化
circleMove++;
// 當圓點到最後一個4 也就是圖片輪播到我們複製的哪一個圖片時 圓點從頭開始
if (circleMove == ol.children.length) {
circleMove = 0
}
// circleMove == ol.children.length - 1 ? 0 : circleMove;
// 調用函數 排他思想
circleVisible();
}
})
// 4.左側按鈕點擊
arrowL.addEventListener('click', function () {
if (flag) {
flag = false;
// (1) 當ul是第一張圖片時 點擊時應輪播到倒數第二張
if (clickCount == 0) {
ul.style.left = -clickCount * focusWidth + 'px';
clickCount = ul.children.length - 1; // 點擊數也回到圖片對應的點擊數
}
clickCount--;
animate(ul, -clickCount * focusWidth, function () {
flag = true;
});
// (2) 圖片輪播時 圓點也在變化
circleMove--;
// 點擊時 如果 circleMove < 0 說明是第一張圖片 小圓點要從第4個開始 (索引號3)
if (circleMove < 0) {
circleMove = ol.children.length - 1
}
// circleMove < 0 ? ol.children.length - 1 : circleMove;
// 調用函數 排他思想
circleVisible();
}
})
// 5.鼠標經過時 設置定時器 自動輪播圖片
// 自動輪播的效果 與點擊右側按鈕的效果一樣
// 即可以使用手動調取 右側按鈕點擊事件
var carousel = setInterval(function autoCarousel() {
arrowR.click();
}, 3000)
// 排他
function circleVisible() {
// 幹掉所有人
for (var i = 0; i < ol.children.length; i++) {
ol.children[i].className = '';
}
// 留下自己
ol.children[circleMove].className = 'current';
}
})
結構部分
這裏有需要注意的一點,輪播圖用到了之前封裝的動畫函數,需要引入動畫的js文件,動畫的js文件要在頁面的js文件之前引入,因爲動畫js是依賴於頁面的js文件的。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./css/lb.css">
<!-- 依賴於lb.js 因爲只有在有js文件時纔會引入動畫函數 所以要在前面引入 -->
<script src="./js/animate.js"></script>
<script src="./js/lb.js"></script>
</head>
<body>
<div class="w">
<div class="focus">
<!-- 左側按鈕 -->
<a href="javascript:;" class="arrow-l">
</a>
<!-- 右側按鈕 -->
<a href="javascript:;" class="arrow-r"></a>
<!-- 核心的滾動區域 -->
<ul>
<li>
<a href="#"><img src="upload/focus.jpg" alt=""></a>
</li>
<li>
<a href="#"><img src="upload/focus1.jpg" alt=""></a>
</li>
<li>
<a href="#"><img src="upload/focus2.jpg" alt=""></a>
</li>
<!-- 注意這是第一張圖片複製過來的 -->
<li>
<a href="#"><img src="upload/focus3.jpg" alt=""></a>
</li>
</ul>
<!-- 小圓圈 -->
<ol class="circle">
</ol>
</div>
</div>
</body>
</html>
ok,輪播圖克服掉了。
春意盎然,我的寒假還在繼續。。。。。。