原生js圖片輪播效果實現(xiàn)代碼
現(xiàn)在很多javascript的插件都可以實現(xiàn)圖片輪播的功能,這篇文章,主要是通過這個domo來解析javascript圖片輪播的原理。
老規(guī)矩,先上代碼。至于代碼中的圖片,隨便找三張即可,最核心的還是理解其思想。
html:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>滾動圖</title> <link rel="stylesheet" type="text/css" href="css/scroll.css"/> </head> <body> <div id="wrapper"> <div id="box"> <img src="img/banner0.png"/> <img src="img/banner1.png"/> <img src="img/banner2.png"/> </div> <div id="pointer"> <span class="active"></span> <span></span> <span></span> </div> </div> <script src="js/scroll.js" type="text/javascript" charset="utf-8"></script> </body> </html>
css:
*{ margin: 0; padding: 0; } #wrapper{ position: relative; width: 1200px; margin: 50px auto; overflow: hidden; } #pointer{ clear: both; position: absolute; right: 500px; bottom: 15px; width: 180px; height: 2px; } #pointer span{ display: block; box-sizing: border-box; float: left; width: 50px; height: 1.5px; margin-right: 10px; border-radius: .5px; background: #fff; opacity: .5; -webkit-opacity: .5; -moz-opacity: .5; filter:alpha(opacity=50); } #pointer .active{ opacity: .8; -webkit-opacity: .8; -moz-opacity: .8; filter:alpha(opacity=80); } #box{ position: relative; width: 3600px; clear: both; } img{ display: block; float: left; width: 1200px; height: 337px; }
javascript:
window.onload = function(){ //獲取裝圖片的盒子 var box = document.getElementById('box'); //獲取裝頁碼的盒子 var pointer = document.getElementById('pointer'); //獲取盒子中的所有圖片 var imglist = box.getElementsByTagName('img') //獲取盒子中的所有頁碼 var pointerList = pointer.getElementsByTagName('span'); //圖片的寬度,正負用于左右的循環(huán) var n = -1200; //增加一倍的圖片用于循環(huán) box.innerHTML = box.innerHTML+box.innerHTML; //設置盒子的寬 box.style.width = imglist[0].offsetWidth*imglist.length+"px"; var timer = null; timer = setInterval(function(){ scroll(box,n,pointerList); },3000); box.onmouseover = function(){ clearInterval(timer); } pointer.onmouseover = function(){ clearInterval(timer); } box.onmouseout = function(){ timer = setInterval(function (){ // console.log(new Date()); scroll(box,n,pointerList); },3000); } //設置頁碼的點擊事件 for(var i=0;i<pointerList.length;i++){ pointerList[i].index=i;//設置一個參數(shù),用下面調用某個頁碼 //如果不設置參數(shù),在調用頁碼的時候會直接調用最后一個,因為我們使用了循環(huán) pointerList[i].onclick=function (){ for(var j=0;j<pointerList.length;j++){ pointerList[j].className='';//清空激活的class } move(box,n*(this.index));//移動圖片 this.className='active';//激活點擊的頁碼 } } } /** * 循環(huán)滾動函數(shù) * @param {Object} box * @param {Object} n */ function scroll(box,n,page){ //判斷是否到達臨界點,即box的中間部分 if(box.offsetLeft<=-box.offsetWidth/2){ box.style.left = "0px";//重新從頭開始 console.log('0'); } if(box.offsetLeft%n!=0){ //因為在我們切換瀏覽器標簽頁或者切換去其他軟件界面的時候, //會影響到setInterval,有時候setInterval會增加好幾秒,在這里我們必須加一個判斷 //只有當它走完了一個整個的圖片寬度時,我們才進行下一次滾動。 } else{ pageScroll(box,n,page); move(box,n+box.offsetLeft); } } /** * 滾動頁碼函數(shù) * @param {Object} box * @param {Object} n * @param {Object} page */ function pageScroll(box,n,page){ //直接通過圖片盒子的定位判斷頁碼值,但是此時的頁碼值是滾動之前的,所以后面的值要+1使用 var index = Math.abs(box.offsetLeft/n); console.log(index); for(var i=0;i<page.length;i++){ page[i].className=''; } //判斷是不是最后一頁,是最后一頁的話+1要變成0; if(index<page.length-1){ page[index+1].className='active'; } else{ page[0].className='active'; } } /** * 變速移動 * @param {Object} ele * @param {Object} target */ function move(ele,target){ clearInterval(ele.timer); console.log(new Date()); ele.timer = setInterval(function () { var step = (target-ele.offsetLeft)/10; step = step>0?Math.ceil(step):Math.floor(step); if(target==ele.offsetLeft){ console.log(new Date()); clearInterval(ele.timer); } else{ ele.style.left = ele.offsetLeft + step + "px"; } },30); }
html和css部分依舊比較簡單,直接跳過。javascript部分的代碼注釋寫的也比較詳細,下面主要講解邏輯部分。
圖片滾動的原理是利用setInterval函數(shù)進行背景圖片的不斷循環(huán)。為了避免圖片循環(huán)的過程中出現(xiàn)間斷,首先是在javascript中進行圖片的復制(增加一倍),然后當?shù)竭_臨界點時,瞬間將圖片移動到初始的位置,然后開始下一輪循環(huán)。
在這個domo中,主要包含四個函數(shù):
1、外層控制間隔時間的函數(shù)。這個比較容易理解,通過setInterval函數(shù)每隔幾秒循環(huán)執(zhí)行一次圖片滾動的函數(shù)。
2、中間層滾動函數(shù)。判斷圖片盒子是否到達臨界點,判斷當前狀態(tài)是否符合進入下一次滾動(這個條件主要是為了防止切換界面對setInterval函數(shù)的影響,具體原因在最后)。
3、中間層頁碼滾動函數(shù)。基本沒有難點,主要是理解頁碼為什么+1即可。
4、圖片滾動函數(shù)。這個在之前寫過的一篇文章有詳細講解,不再贅述,參考:http://www.dbjr.com.cn/article/95211.htm
最后,一點關于setInterval底層機制的擴展。
我們內(nèi)層函數(shù)的執(zhí)行事件正常情況下為1-2s(測試過),而外層的循環(huán)需要3s才進行一次,正常的情況是沒有問題的。但是,當你切換界面的時候,瀏覽器就會對setInterval函數(shù)產(chǎn)生影響,此時執(zhí)行事件的事件就會超過3面,在沒移動結束的情況下開啟另一個定時器進行下一次圖片滾動,所以就會發(fā)生錯亂。
javascript是單線程的,當你使用setInterval函數(shù)的時候并不是真正暫停,而是先掛起這個事件,繼續(xù)執(zhí)行下面的事件,而當這個事件要執(zhí)行時,如果瀏覽器當前沒有任務,那么它會立馬執(zhí)行,但是如果瀏覽器有任務,那么就會有一定的延遲,這也是為什么切換界面會對setInterval函數(shù)的時間產(chǎn)生影響。
(關于setInterval函數(shù)的理解如有錯誤,歡迎指正!如果大家想要深入理解,也可以去一些大神的博客看一下setInterval函數(shù)的文章)
精彩專題分享:jQuery圖片輪播 JavaScript圖片輪播 Bootstrap圖片輪播
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
拖動table標題實現(xiàn)改變td的大小(css+js代碼)
拖動列寬的表格table標題同時改變td的大小,本文將以實例演示為大家呈現(xiàn),感興趣的朋友可以參考下哈,希望對你學習js或者css有所幫助2013-04-04原生JS實現(xiàn)圖片輪播 JS實現(xiàn)小廣告插件
這篇文章主要為大家詳細介紹了原生JS實現(xiàn)圖片輪播、小廣告插件,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-09-09