js原生實現輪播圖效果(面向對象編程)
阿新 • • 發佈:2019-05-06
alt 狀態 off wid 編程) .proto eat doc 持續時間
面向對象編程js原生實現輪播圖效果
1.先看效果圖
2.需要實現的功能:
- 自動輪播
- 點擊左右箭頭按鈕無縫輪播
- 點擊數字按鈕切換圖片
分析:如何實現無縫輪播?
在一個固定大小的相框裏有一個ul標簽,其長度是幾個圖片寬度的總和,通過translateX()的方法來實現左右移動動畫。
如何實現無縫呢?比如有三張圖片,可以在把第一張圖片通過cloneNode的方法克隆下來放到第三張圖片後面。圖片順序 1,2,3,1,看下面的HTML結構,結構中並沒有4張圖,第四張圖是生成的。
3.html結構
<!-- ul是圖片盒子,ol是數字按鈕盒子,最下面的div是左右箭頭按鈕盒子 --> <div class="container"> <div id="screen"> <ul> <li><img src="./img/1.jpg" alt=""></li> <li><img src="./img/2.jpg" alt=""></li> <li><img src="./img/3.jpg" alt=""></li> </ul> <ol> <!--<li class="active">1</li>--> <!--<li>2</li>--> <!--<li>3</li>--> </ol> </div> <div> <span><</span> <span>></span> </div> </div>
4.功能實現
4.1 創建對象
創建一個對象,需要傳入一個相框盒子元素,通過這個元素來獲取盒子中其他需要的元素,並把這些作為這個Carousel對象的屬性:
function Carousel(el) { this.screen = el; // 相框 this.width = this.screen.offsetWidth; // 相框寬度 this.ulBox = this.screen.children[0]; // ul盒子 this.list = this.ulBox.children; // ul下面所有li this.olBox = this.screen.children[1]; // 數字按鈕盒子 this.arrow = this.screen.nextElementSibling; // 箭頭盒子 this.leftArraw = this.arrow.children[0]; // 左箭頭 this.rightArraw = this.arrow.children[1]; // 右箭頭 this.index = 0; // 數字按鈕的索引 this.timeId = null; // 定時器的id this.activeClass = 'active'; // 數字按鈕class名 this.durtion = '.35s'; // 動畫持續時間 }
4.2動畫效果由translateX實現
// 動畫
Carousel.prototype.animate = function (target) {
this.ulBox.style.transform = 'translateX(' + target + 'px)'
};
4.3根據輪播圖片個數生成數字按鈕節點
生成節點後,為新生成的節點添加點擊事件,實現每次點擊根據節點對應的index切換圖片,這裏實現的需求的第三個功能。
// 創建節點 Carousel.prototype.createNodes = function () { let self = this; // 創建按鈕節點 for (let i = 0; i < self.list.length; i++) { let liObj = document.createElement('li'); liObj.innerText = i + 1; self.olBox.appendChild(liObj); // 為生成的數字按鈕添加點擊事件 liObj.onclick = function () { self.index = this.innerText - 1; // 獲取當前點擊對象的索引值 self.switch_sel(); self.animate(-self.index * self.width); }; } // 默認顯示第一張圖片,第一個數字按鈕默認選中狀態 self.olBox.children[0].className = self.activeClass; // 克隆第一張圖放到ulBox後面,實現無縫輪播 self.ulBox.appendChild(self.ulBox.children[0].cloneNode(true)); };
4.4輪播圖數字按鈕點擊切換狀態
因為多次用到這段代碼,所有就寫成一個方法掛在Carousel對象上了
// 切換數字按鈕的選中狀態
Carousel.prototype.switch_sel = function(){
let self = this;
for (let i = 0; i < self.olBox.children.length; i++) {
self.olBox.children[i].removeAttribute('class');
}
self.olBox.children[self.index].className = self.activeClass;
};
4.5輪播事件,也是點擊右箭頭的事件
// 輪播事件
Carousel.prototype.clickHandle = function () {
let self = this;
// 如果是最後一張圖,直接跳到第一張
if (self.index === self.list.length - 1) {
self.index = 0;
// 當點擊到最後一張時直接跳到第一張
self.ulBox.style.transitionDuration = '0s';
self.animate(-self.index * self.width);
}
// 必須有時間延遲,否則圖片跳轉切換不成功,因為self.animate()沒有來得及執行就被後面的self.animate()函數覆蓋了。
setTimeout(function () {
self.ulBox.style.transitionDuration = self.durtion;
self.index++;
self.animate(-self.index * self.width);
// 如果是最後一張圖,則去掉最後一個的class屬性,切換到第一個
if (self.index === self.list.length - 1) {
self.olBox.children[self.olBox.children.length - 1].removeAttribute('class');
self.olBox.children[0].className = self.activeClass;
} else { // 切換當前選中狀態
self.switch_sel();
}
}, 20);
};
4.6事件綁定
為左右箭頭點擊綁定事件,同時當鼠標hover在相框上時自動輪播取消,鼠標離開相框時自動輪播開始執行。
// 事件綁定
Carousel.prototype.bindEvent = function () {
let self = this;
// 又點擊下一張
self.rightArraw.onclick = function () {
self.clickHandle();
};
// 左點擊上一張
self.leftArraw.onclick = function(){
if(self.index === 0){
self.index = self.list.length - 1;
// 直接跳到最後一張
self.ulBox.style.transitionDuration = '0s';
self.animate(-self.index * self.width);
}
setTimeout(function(){
self.ulBox.style.transitionDuration = self.durtion;
self.index--;
self.animate(-self.index * self.width);
self.switch_sel();
}, 20);
};
// 鼠標懸停清除定時器
self.screen.parentElement.onmouseover = function(){
self.timeId && clearInterval(self.timeId);
self.arrow.style.display = 'flex';
};
// 鼠標離開打開定時器
self.screen.parentElement.onmouseout = function(){
self.timeId = setInterval(self.clickHandle.bind(self), 2000);
self.arrow.style.display = 'none';
}
};
4.7初始化方法
初始化方法中創建節點,綁定事件,同時設定定時器實現自動輪播效果。
// 初始化
Carousel.prototype.init = function () {
this.createNodes();
this.bindEvent();
this.timeId = setInterval(this.clickHandle.bind(this), 2000);
// 註意這裏要bind(this) 否則clickHandle中的this指向window
};
4.8實例化Carousel對象,大功告成
實例化一個輪播圖對象,然後調該對象的init方法。
只要html結構相同,只需要傳入不同的相框元素,就可以在同一個頁面中實例化多個輪播圖對象。也就是說,同一個頁面的多處輪播效果。
let carousel = new Carousel(document.getElementById('screen'));
carousel.init();
5備註
全部的代碼和css樣式可參考我的github中的輪播圖倉庫,菜鳥程序猿一枚,程序設計如果有不妥的地方歡迎提出意見或建議,當然啦,如果你喜歡並star了我的這個倉庫,我會很開心的 : )
[1]: https://github.com/jiangleiundo/carousel
js原生實現輪播圖效果(面向對象編程)