輪播圖外掛(Broadcast.js)
前言:寫這個外掛的原因
- 前段時間準備用vue加上網易雲的nodejs介面,模擬網易雲音樂移動端。因為想自己寫一遍所有的程式碼以及加固自己的flex佈局,所以沒有使用UI元件。在輪播圖部分,本來在vue裡面寫了一下,但是發現總是出現bug,所以後來準備封裝一個外掛來實現。
- 其次的一個原因是,以為這一學期學vue一直在用vue,發現自己以前學的原生js有點遺忘,所以想借這個機會再次複習一下js。
功能&介紹
- 沒有引用第三方外掛庫,原生js,封裝一個Broadcast物件,在此物件上展開,僅僅190多行程式碼。
- 目前主要實現了:無縫輪播,自動播放,PC端左右按鈕點選切換,移動端手勢滑動切換。
- 自己寫了一部分基礎的css樣式,可以再次的基礎上修改成自己喜歡的樣式。
展示介面&使用
-
PC端展示:
-
移動端展示:
Usage
普通頁面引用
-
複製github倉庫下面,
src/js
檔案下的broadcast-me.js
放到自己專案檔案中 -
複製github倉庫下面,
src/css
檔案下的broadcast-me.css
放到自己專案檔案中 -
在頁面中引入:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <!-- 引入外掛的css檔案 --> <link rel="stylesheet" href="./css/broadcast-me.css"> </head> <body> <!-- 引入外掛的js檔案 --> <script src="./js/broadcast-me.js"></script> </body> </html> 複製程式碼
-
在後面如果需要一個輪播圖,則實列化這個物件:
var box = document.getElementById('box'); var imagesAndUrl = [{ imgSrc : './img/1.jpg', linkHref : "#" },{ imgSrc : './img/2.jpg', linkHref : '1' },{ imgSrc : './img/3.jpg', linkHref : '#' },{ imgSrc : './img/4.jpg', linkHref : '#' },{ imgSrc : './img/5.jpg', linkHref : '#' }]; // box => 你需要建立輪播圖的父級元素 // imagesAndUrl => 陣列,存放圖片地址以及圖片的連線地址 var broadcast = new Broadcast(box,imagesAndUrl,{ transitionTime : 800, // 動畫過渡時間,預設為800ms intervalTime : 5000 // 圖片切換時間,預設為5s }); 複製程式碼
VUE中引用
- 在vue中使用,在
broadcast-me.js
檔案最後加上:
// 向外界暴露Broadcas物件
module.exports = Broadcast;
複製程式碼
-
在需要使用輪播的元件中,引入我們的檔案
-
在模板檔案中,採用自定義指令的方式,來插入我們的輪播圖
<template>
<div class="broadcast" v-broadcast="broadcastImg">
<!-- 自定義指令broadcast,,形參 => broadcastImg 為我們的輪播圖資料 -->
</div>
</template> imgSrc : './img/5.jpg',
linkHref : '#'
}
複製程式碼
- 新增自定義指令:
directives:{
broadcast:{
inserted:function(el,binding) {
// binding.value 為我們傳入的形參,即圖片的地址和圖片點選連結
var broadcast = new Broadcast(el,binding.value,{
transitionTime : 800, // 動畫過渡時間,預設為800ms
intervalTime : 5000 // 圖片切換時間,預設為5s
});
}
}
}
複製程式碼
API
// 構造的物件
new Broadcast (el,imagesAndUrl,JSON)
複製程式碼
屬性 | 說明 | 備註備註 |
---|---|---|
el | 你需要建立輪播圖的包裹(父級)元素 | 不寫報錯 |
imagesAndUrl | 圖片的地址與圖片地址連結。陣列物件 linkHref => 圖片點選連結;imgSrc => 圖片地址 | 不寫報錯 |
JSON | transitionTime => 動畫過渡時間, intervalTime => 動畫切換時間 | 預設:過渡時間 => 800ms 切換時間 => 5s |
程式碼編寫思路
dom 節點的動態生成
- 通過 el 的寬度,生成一個動態css加入到頁面當中
// 動態新增一些css樣式
let cssStr = `.broadcastMe .broadcastMe-list {width: ${(this.imagesAndUrl.length+2)*this.el.clientWidth}px;}.broadcastMe .broadcastMe-list .broadcastMe-item {width:${this.el.clientWidth}px;}`;
let styleNode = document.createElement('style');
styleNode.innerText = cssStr;
document.head.appendChild(styleNode)
複製程式碼
- 通過字串模板的形式,生成我們需要的且符合無縫輪播的html字串,載入el節點當中。
移動端手勢滑動
通過:touchstart => touchmove => touchend 完成一個滑動的全過程,並在touchmove事件當中,改變當前的left值,並在touchend事件當中判斷左右2邊的距離,進行翻頁還是不變。
// 移動端手指滑動
let stratPointX = 0;
let offsetX = 0;
this.el.addEventListener("touchstart", (e) => {
stratPointX = e.changedTouches[0].pageX;
offsetX = this.broadcastMeList.offsetLeft;
this.animationMark = true;
})
this.el.addEventListener("touchmove", (e) => {
let disX = e.changedTouches[0].pageX - stratPointX;
let left = offsetX + disX;
this.broadcastMeList.style.transitionProperty = 'none';
this.broadcastMeList.style.left = left + 'px';
})
this.el.addEventListener("touchend", () => {
let left = this.broadcastMeList.offsetLeft;
// 判斷正在滾動的圖片距離左右圖片的遠近,
this.index = Math.round(-left/this.el.clientWidth);
this.animationMark = false;
this.render();
})
複製程式碼
渲染函式(☆)
Broadcast.prototype.render = function () {
// 防抖控制
if(this.animationMark) return;
this.animationMark = true;
// 修改broadcastMeList 的left值
this.broadcastMeList.style.left = (-1)*this.el.clientWidth*this.index + 'px';
this.broadcastMeList.style.transition = 'left ' + this.timer/1000 + 's';
setTimeout(() => {
// 新增判斷,防止出界
if(this.index <= 0){
// 無縫輪播,修改真實的left值,取消transition,造成視覺錯誤
this.broadcastMeList.style.transitionProperty = 'none';
this.index = this.imagesAndUrl.length;
this.broadcastMeList.style.left = (-1)*this.el.clientWidth*this.index + 'px';
}else if (this.index > this.imagesAndUrl.length){
this.broadcastMeList.style.transitionProperty = 'none';
this.index = 1;
this.broadcastMeList.style.left = (-1)*this.el.clientWidth*this.index + 'px';
}
this.animationMark = false;
},this.timer)
this.renderSpot();
}
複製程式碼
最後
因為才疏學淺,程式碼才剛剛寫完,測試較少,很多bug還未發現,如果發現問題,歡迎留言指出,敬請斧正。謝謝!!