自己一直想寫一個真正能用的輪播圖,以前是寫過一個,但是不是無縫的輪播,感覺體驗很差,這個輪播之前也搞了很多實例,看了很多代碼,但是腦子總轉不過彎,為什么在運動到一定距離后可以突然轉回到原始位置,而沒有出現運動情況?為什么我清楚定時器了,還是出現定時器重疊的情況,導致輪播混亂?如何讓左右按鈕,分頁按鈕,輪播函數聯系起來,在觸發一個事件的時候,輪播能正常運行?如何在第一個li的時候向左(上一張)滑動?
平時自己有空就想,試過很多方法,但是始終搞不出來,今天看了別人寫的插件,后發現:
1.當ul滾動到最后一張的時候,瞬間回到初始位置,而沒有動作,是應為我們都把這個回到初始位置的瞬間當作了運動的一部分了。
2.關於定時器重疊的,問題,以前我試過通過if(timer){clearInterval(timer)}的方法,但是不好用,應為點擊分頁的時候,還是會出現問題,最后看了別人的代碼,發現通過鼠標移入slider之后,清除定時器,可以一勞永逸的解決了這個問題,因為,當鼠標移入slider之后,定時器被清除,而在沒有重新啟動定時器之前的一切操作,都是在沒有自動輪播的情況下進行的。
3.讓左右按鈕,分頁按鈕,輪播函數結合,我是這么想的,輪播函數可以獨立,然后通過獲取當前的offsetLleft,后運動之后的offsetLleft來決定運動距離和方向,然后左右按鈕只需通過設置每個li的寬度的正負值傳參就可以聯系起來,而分頁函數和左右函數,則通過index的增減,傳參聯系起來,分頁函數與輪播函數,通過獲取當前分頁的索引值和點擊分頁的索引值聯系起來,當然這個索引值,可以通過setAttibute和getAttribute來設置獲取。
4.關於最后一個問題,我們都知道如果當前頁為第一頁的時候,如果點擊上一張的話,會出現空白,反正就是錯,所以我們在初始化的時候,需要在最前面添加最后一個滾動單位(最后一張圖片的li),為了讓滾動到最后一個li能返回初始位置,也要在ul的最后添加第一個li,如果你覺得,這樣會不會影響到分頁呢。其實分頁我們可以通過獨立設置data-index,還有分頁的length也可以通過初始化之前的來設置,因為當時並沒有添加節點。
html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title>demo3</title> <meta name="description" content=""> <meta name="keywords" content=""> <link href="" rel="stylesheet"> <style type="text/css"> ul{ padding:0px; margin:0px; } #slider{ width:400px; height:200px; position: relative; margin:400px auto; overflow: hidden; border:1px solid #eee; } #prev{ width:50px; height:30px; line-height: 30px; color:#fff; background:#000; text-align: center; position: absolute; opacity:0.5; left:-200px; text-decoration: none; top:50%; z-index:100; margin-top:-15px; } #next{ opacity:0.5; text-decoration: none; z-index:100; width:50px; height:30px; line-height: 30px; color:#fff; background:#000; text-align: center; position: absolute; right:-200px; top:50%; margin-top:-15px; } #slider ul{ height:200px; position: absolute; left:0px; top:0px; } #slider ul li{ width:400px; height:200px; background:orange; list-style: none; text-align: center; line-height: 200px; font-size:100px; font-weight:bold; color:#fff; float:left; } #slider ol{ list-style-type: none; position: absolute; bottom:10px; padding:0; margin:0; width:100%; text-align: center; } #slider ol li{ width:10px; height:10px; display: inline-block; background: #000; opacity: 0.3; cursor:pointer; margin:5px; border-radius: 50%; } #slider ol li.on{ opacity: 0.8; } </style> </head> <body> <div id="slider"> <a href="javascript:;" id="prev">prev</a> <a href="javascript:;" id="next">next</a> <ul> <li> 1 </li> <li> 2 </li> <li> 3 </li> </ul> <ol> </ol> </div> </body> </html>
javascript
<script type="text/javascript" src="startmove.js"></script> <script type="text/javascript"> window.onload = function (){ var slider = document.getElementById('slider'); var oUl = slider.getElementsByTagName('ul')[0]; var oLi = oUl.getElementsByTagName('li'); var liWidth = parseInt(getStyle(oLi[0] , 'width')); var aNext = document.getElementById('next'); var aPrev = document.getElementById('prev'); var timer = null; var inter = 3000; var index = 0; var oOl = slider.getElementsByTagName('ol')[0]; var pLi = oOl.getElementsByTagName('li'); var b = false; //初始化 function intSlider(){ for(var i = 0 ; i < oLi.length ; i++){ oLi[i].setAttribute('data-index',i); } for( var i = 0 ; i < oLi.length; i++){ var iLi = document.createElement('li'); oOl.appendChild(iLi); } for(var i = 0 ; i < pLi.length ; i++){ pLi[i].setAttribute('data-index',i) } pLi[0].className = 'on'; var cloneLastLi = oLi[oLi.length-1].cloneNode(true); var cloneFirstLi = oLi[0].cloneNode(true); oUl.insertBefore(cloneLastLi,oUl.childNodes[0]); oUl.appendChild(cloneFirstLi); oUl.style.left = -parseInt(getStyle(oLi[0] , 'width')) + 'px'; }; intSlider(); //重新設定ul寬度 function getWidth(){ var liWidth = parseInt(getStyle(oLi[0] , 'width')); oUl.style.width = oLi.length * liWidth + 'px'; }; getWidth(); //鼠標移入移除直接清除了timer,就省了很多清除定時器的麻煩 slider.onmouseover = function() { if(timer){ clearInterval(timer); } startMove(aNext,{right : 20}); startMove(aPrev,{left : 20}); }; slider.onmouseout = function() { timer = setInterval(nextSlider , inter); startMove(aNext,{right : -100}); startMove(aPrev,{left : -100}); }; //核心函數 function sliderOffset(offset){ b = true; //當前left和滾動之后的left var currentLeft = oUl.offsetLeft; var afterLeft = currentLeft + offset; startMove(oUl , {left : afterLeft},function(){ if (oUl.offsetLeft <= -(oUl.offsetWidth) + liWidth) { oUl.style.left= -liWidth + 'px'; } else if (oUl.offsetLeft >= 0) { oUl.style.left= -(oLi.length - 2) * liWidth + 'px'; }; b = false; }); }; //當前分頁函數 function pageSlider(index){ for(var i = 0; i < pLi.length ; i++){ if(pLi[i].className == 'on'){ pLi[i].className = ''; } } pLi[index].className = 'on'; }; //分頁點擊函數 for(var i = 0 ; i< pLi.length ; i++){ pLi[i].onclick = function (){ var index1 = this.getAttribute('data-index'); var offset = (index - index1) * liWidth; sliderOffset(offset) index = index1; pageSlider(index); } }; //上一張函數 function nextSlider(){ if(b){ return; } sliderOffset(-liWidth) if(index >= pLi.length-1){ index = 0; }else{ index++ } pageSlider(index) }; //下一張函數 function prevSlider(){ if(b){ return; } sliderOffset(liWidth); if(index <= 0){ index = pLi.length-1; }else{ index-- } pageSlider(index); }; //事件綁定兼容函數 function addEvent(element,event,listener){ if(element.addEventListener){ element.addEventListener(event,listener,false); }else{ element.attachEvent('on' + event , listener); } }; //綁定事件 addEvent(aNext,'click',nextSlider); addEvent(aPrev,'click',prevSlider); //樣式獲取 function getStyle(obj, attr){ if(obj.currentStyle){ return obj.currentStyle[attr] }else{ return getComputedStyle(obj,false)[attr] } }; //自動輪播 timer = setInterval(nextSlider, inter); } </script>