原生js封裝無縫輪播功能
原生js封裝無縫輪播插件,供大家參考,具體內(nèi)容如下
說明:
這是一個(gè)使用原生js、es5語(yǔ)法寫出的無縫輪播程序,代碼中對(duì)相關(guān)api進(jìn)行了封裝,使得在引入該輪播js文件后,只需要在自己的js文件中添加兩行代碼即可在網(wǎng)頁(yè)中實(shí)現(xiàn)一個(gè)基本的無縫輪播圖效果。
基本使用步驟為:獲取dom元素?cái)?shù)組、向輪播對(duì)象中傳參、輪播對(duì)象調(diào)用自動(dòng)輪播方法。
除基本的定時(shí)器自動(dòng)輪播功能外,該程序還支持設(shè)置過渡動(dòng)畫時(shí)間、設(shè)置鼠標(biāo)移入元素自動(dòng)輪播停止、設(shè)置點(diǎn)擊左右側(cè)邊按鈕時(shí)輪播、設(shè)置點(diǎn)擊下方按鈕時(shí)輪播功能。
該程序不需要依賴css、html文件、但需要你的css、html布局遵循一定的規(guī)則。
注意該程序不支持曲線過渡速度、且在將瀏覽器切換瀏覽器窗口后有時(shí)會(huì)出現(xiàn)輪播圖錯(cuò)亂的bug,暫時(shí)找不到問題的所在。
該程序僅是我一個(gè)初學(xué)者對(duì)無縫輪播函數(shù)的簡(jiǎn)單封裝,僅能夠做學(xué)習(xí)和參考使用。
下面除輪播代碼外,我還會(huì)給出示例程序。
運(yùn)行效果:
思路:
根據(jù)輪播的方向確定所有輪播圖元素的排列順序,如果當(dāng)前輪播圖已到達(dá)所有輪播圖的邊界,則將相對(duì)方向上的最后一張輪播圖瞬間移動(dòng)到相應(yīng)位置。
使用這種方法實(shí)現(xiàn)輪播圖所需要的最少輪播圖數(shù)為3張,針對(duì)輪播圖數(shù)量為一張和兩張的情況則需要對(duì)其單獨(dú)處理,一張情況下,復(fù)制添加兩張和當(dāng)前輪播圖相同的輪播圖元素,兩張情況下,需要按順序?qū)Ξ?dāng)前輪播圖進(jìn)行復(fù)制添加。
編譯環(huán)境:
Chrome 86.0.4240.183
代碼:
slide.js 封裝輪播圖代碼
(function(window, undefined) { // 獲取元素css屬性值 function getCss(elem, attr) { return elem.currentStyle ? elem.currentStyle[attr] : window.getComputedStyle(elem, null)[attr]; } // 去除字符串中的非數(shù)字,不包括負(fù)號(hào) function toInt(str) { var rex = /[^0-9]/ig; return Number((str[0] === '-' && str[1] !== '=') ? '-' + str.replace(rex, '') : str.replace(rex, '')); } // 封裝動(dòng)畫函數(shù),參數(shù):dom對(duì)象、css屬性值對(duì)象、動(dòng)畫執(zhí)行時(shí)間、動(dòng)畫完成后回調(diào) function animation(elem, params, speed, callback) { for (var param in params) { (function(param) { var elemValue = toInt(getCss(elem, param)), targetValue = toInt(params[param]), currentDis = elemValue, unit = params[param].substr(params[param].indexOf('[A-Za-z]+') - 1); if (params[param].length > 2) { var prefix = params[param].substr(0, 2); if (prefix === '+=') targetValue = elemValue + targetValue; else if (prefix === '-=') targetValue = elemValue - targetValue; } var dis = (targetValue - elemValue) / speed, sizeFlag = targetValue < elemValue; var timer = setInterval(function() { elemValue = toInt(getCss(elem, param)); if (sizeFlag) { if (currentDis <= targetValue) { clearInterval(timer); elem.style[param] = targetValue + unit; } else { currentDis += dis; elem.style[param] = currentDis + unit; } } else { if (currentDis >= targetValue) { clearInterval(timer); elem.style[param] = targetValue + unit; } else { currentDis += dis; elem.style[param] = currentDis + unit; } } }, 1); })(param); } if (typeof callback === 'function') callback(); }; // 向右輪播數(shù)組移動(dòng) function rightRoundArrayMove() { var winsLen = wins.length; var lastWin = wins[winsLen - 1]; for (var i = winsLen - 1; i > 0; i--) wins[i] = wins[i - 1]; wins[0] = lastWin; } // 向左輪播 function rightRound(time) { rightRoundArrayMove(); wins.forEach(function(win, index) { (index === 0) ? win.style.left = index * winWidth - winWidth + 'px' : animation(win, {left: '+=' + winWidth + 'px'}, time ? time : animationTime); }); } // 向右輪播 function leftRound(time) { var winsLen = wins.length; var firstWin = wins[0]; for (var i = 0; i < winsLen - 1; i++) wins[i] = wins[i + 1]; wins[winsLen - 1] = firstWin; wins.forEach(function(win, index) { (index === wins.length - 1) ? win.style.left = index * winWidth - winWidth + 'px' : animation(win, {left: '-=' + winWidth + 'px'}, time ? time : animationTime); }); } var // wins, btns, sbtns用于保存構(gòu)造函數(shù)的參數(shù) wins, btns, sbtns, // 窗口的寬度 winWidth, // 過渡動(dòng)畫時(shí)間(毫秒),默認(rèn)為100 animationTime = 100, // 點(diǎn)擊按鈕輪播間隔 clickInterval = animationTime << 2, // 保存自動(dòng)輪播定時(shí)器、定時(shí)器間隔、是否向右輪播 autoRoundTimer, qinterval, qisRight, // slide構(gòu)造函數(shù),參數(shù):窗口數(shù)組,按鈕數(shù)組,側(cè)邊按鈕數(shù)組 slide = function(wins, btns, sbtns) { return new slide.prototype.init(wins, btns, sbtns); }; slide.prototype = { // 初始化窗口元素 init: function(awins, abtns, asbtns) { if (!awins) throw new Error('The window array cannot be empty.'); wins = Object.values(awins), btns = abtns, sbtns = asbtns; // 處理窗口少于3個(gè)的情況 if (wins.length === 1) { var winParent = wins[0].parentNode; var winHTML = wins[0].outerHTML; winParent.innerHTML += winHTML + winHTML; wins = Object.values(winParent.children); } else if (wins.length === 2) { var winParent = wins[0].parentNode; winParent.innerHTML += wins[0].outerHTML + wins[1].outerHTML; wins = Object.values(winParent.children); } winWidth = wins[0].offsetWidth; wins.forEach(function(win, index) { win.style.position = 'absolute'; win.index = index; }); rightRoundArrayMove(); wins.forEach(function(win, index) { win.style.left = index * winWidth - winWidth + 'px'; }); }, // 設(shè)置過渡動(dòng)畫時(shí)間 setAnimationTime: function(time) { animationTime = time; clickInterval = animationTime << 2; }, // 自動(dòng)輪播,參數(shù):輪播時(shí)間間隔、是否為向右輪播 autoRound: function(interval, isRight) { autoRoundTimer = setInterval(function() { isRight ? rightRound() : leftRound(); }, interval); qinterval = interval; qisRight = isRight; }, // 側(cè)邊按鈕點(diǎn)擊,參數(shù)為側(cè)邊按鈕元素?cái)?shù)組,該參數(shù)可在構(gòu)造函數(shù)中傳遞或現(xiàn)在傳遞 sideBtnClickRound: function(sabtns) { var leftBtn = sabtns ? sabtns[0] : sbtns[0], rightBtn = sabtns ? sabtns[1] : sbtns[1]; var isclick= true; leftBtn.onclick = function () { if(isclick) { isclick= false; rightRound(); setTimeout(function() { isclick = true; }, clickInterval); } }; rightBtn.onclick = function () { if(isclick) { isclick= false; leftRound(); setTimeout(function() { isclick = true; }, clickInterval); } }; }, // 普通按鈕點(diǎn)擊,參數(shù):普通按鈕數(shù)組、回調(diào) btnsClickRound: function(abtns, callback) { var ibtns = abtns ? abtns : btns; var isclick= true; ibtns.forEach(function(btn, index) { btn.onclick = function() { if(isclick) { isclick= false; if (typeof callback === 'function') callback(ibtns, btn, index); var poor = index - wins[1].index; var count = Math.abs(poor); if (poor < 0) { var absPoor = count; var timer = setInterval(function() { console.log((absPoor + 1)) rightRound(animationTime / (absPoor + 2)); if ((--count) === 0) clearInterval(timer); }, animationTime); } else if (poor > 0) { var timer = setInterval(function() { leftRound(animationTime / (poor + 2)); if ((--count) === 0) clearInterval(timer); }, animationTime); } setTimeout(function() { isclick = true; }, clickInterval << 1); } } }); }, // 設(shè)置鼠標(biāo)移入取消自動(dòng)輪播,參數(shù):移入的元素、移入元素回調(diào)、移出元素回調(diào) setOverStop: function(box, overCallback, outCallback) { box.onmouseover = function(e) { clearInterval(autoRoundTimer); if (typeof overCallback === 'function') overCallback(e); } box.onmouseout = function(e) { slide.prototype.autoRound(qinterval, qisRight); if (typeof outCallback === 'function') outCallback(e); } } } slide.prototype.init.prototype = slide.prototype; window.slide = _slide = slide; })(window);
test.js 測(cè)試示例js代碼:
onload = function() { var wins = document.querySelectorAll('.wins > li'); var btns = document.querySelectorAll('.btns > li'); var sideBtns = document.querySelectorAll('.side-btns > div'); var box = document.querySelector('.box'); var s = slide(wins, btns, sideBtns); // 創(chuàng)建輪播對(duì)象,參數(shù):窗口dom數(shù)組、下方按鈕dom數(shù)組(可選)、 s.autoRound(2000); // 設(shè)置自動(dòng)輪播 s.setAnimationTime(200); // 設(shè)置過渡動(dòng)畫時(shí)間 s.setOverStop(box); // 設(shè)置鼠標(biāo)移入元素時(shí)自動(dòng)輪播停止,參數(shù):移入的dom元素、移入元素回調(diào)、移出元素回調(diào) s.sideBtnClickRound(); // 設(shè)置點(diǎn)擊側(cè)邊按鈕時(shí)輪播,參數(shù):按鈕dom數(shù)組(可選) s.btnsClickRound(); // 設(shè)置下方按鈕點(diǎn)擊時(shí)輪播,參數(shù):按鈕dom數(shù)組(可選)、回調(diào) }
html、css示例代碼
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <style type="text/css"> * { margin: 0; padding: 0; } li { list-style: none; } .box { width: 1000px; height: 400px; margin: 20px auto; display: flex; align-items: center; position: relative; overflow: hidden; } .box > * { position: absolute; } .side-btns { width: inherit; height: 100px; display: flex; justify-content: space-between; z-index: 2; } .side-btns > div { width: 50px; height: inherit; text-align: center; line-height: 100px; font-size: 18px; background-color: rgba(0, 0, 0, .3); color: white; cursor: pointer; user-select: none; } .btns { width: inherit; height: 20px; display: flex; justify-content: flex-end; z-index: 2; position: absolute; bottom: 20px; } .btns > li { width: 16px; height: 16px; border-radius: 50%; margin-right: 12px; cursor: pointer; background-color: rgba(0, 0, 0, .2); } .wins { width: inherit; height: inherit; display: flex; } .wins > li { width: inherit; height: inherit; flex-grow:0; flex-shrink:0; } </style> <script src="js/slide.js"></script> <script src="js/test.js"></script> </head> <body> <div class="box"> <div class="side-btns"> <div class="left-btn"><</div> <div class="right-btn">></div> </div> <ul class="btns"> <li></li> <li></li> <li></li> <li></li> </ul> <ul class="wins"> <li style="background-color: antiquewhite;">a</li> <li style="background-color: aquamarine;">b</li> <li style="background-color: green;">c</li> <li style="background-color: brown;">d</li> </ul> </div> </body> </html>
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
js確認(rèn)框confirm()用法實(shí)例詳解
這篇文章主要針對(duì)js確認(rèn)框confirm()用法進(jìn)行實(shí)例講解,介紹了javascript確認(rèn)框的三種使用方法,感興趣的小伙伴們可以參考一下2016-01-01JavaScript實(shí)現(xiàn)購(gòu)物車案例
這篇文章主要為大家詳細(xì)介紹了JavaScript實(shí)現(xiàn)購(gòu)物車案例,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01TypeScript使用函數(shù)重載確定返回類型的實(shí)現(xiàn)方法
這篇文章主要介紹了TypeScript使用函數(shù)重載確定返回類型的實(shí)現(xiàn)方法,文中通過代碼示例講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-03-03Three.js如何用軌跡球插件(trackball)增加對(duì)模型的交互功能詳解
這篇文章主要給大家介紹了關(guān)于Three.js如何用軌跡球插件,也就是trackball增加對(duì)模型的交互功能的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。2017-09-09原生js驗(yàn)證簡(jiǎn)潔注冊(cè)登錄頁(yè)面
這篇文章主要為大家詳細(xì)介紹了原生js驗(yàn)證簡(jiǎn)潔美觀注冊(cè)登錄頁(yè)面的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-12-12微信小程序仿朋友圈發(fā)布動(dòng)態(tài)功能
這篇文章主要介紹了微信小程序仿朋友圈發(fā)布動(dòng)態(tài)界面,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-07-07通過一次報(bào)錯(cuò)詳細(xì)談?wù)凱oint事件
這篇文章主要給大家介紹了關(guān)于如何通過一次報(bào)錯(cuò)詳細(xì)談?wù)凱oint事件的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2018-05-05