需求:實現輪播圖,圖片無縫切換,自動播放。
實現效果:
思考一下:在圖片列表后面多加一張圖片,這張圖片是第一張圖片(為了確保無縫銜接)。圖片就是平鋪放在一個pic里面的,每次移動就是改變的pic的left值。
來擼代碼~~。所有的代碼放在最后面,這里只講一些重要的方法:
為防止懵逼:先貼出封裝函數move()的代碼供參考
function move(ele, attr, speed, target, callback){
//獲取當前的位置
//從左往右進行移動 --- current<target speed
//從右往左進行移動 --- current>target -speed
var current = parseInt(getStyle(ele, attr));
// 810 > 800
if(current>target){
speed = -speed;
}
//定時器累加問題 --- 先清除再開啟
clearInterval(ele.timer);
ele.timer = setInterval(function(){
//獲取元素的現在位置
var begin = parseInt(getStyle(ele, attr));
//步長
var step = begin + speed;
//判斷當step>800, 讓step = 800
//從左往右進行移動 --- speed>0 正值
//從右往左進行移動 --- speed<0 負值
// -10 0 10 超過800直接變成 800
if(speed<0 && step<target || speed>0 && step>target){
step = target;
}
//賦值元素
ele.style[attr] = step + "px";
//讓元素到達目標值時停止 800px
if(step == target){
clearInterval(ele.timer);
//當move函數執行完畢后, 就執行它了
//當條件都滿足時才執行callback回調函數
callback && callback();
}
},30)//步長是30
}
第一步:我們先來實現那個圓形按鈕的點擊事件。 //說明一下,setBtn();是設置按鈕的背景跟隨。像這樣。
第二步:實現左右兩個按鈕的點擊事件
先做右邊的點擊事件,實現
//onNext function Next(){ index ++;
//len 指的是圖片的數組的個數 - 2 因為span按鈕只有5個,索引從0到4 if(index > len) { index = 0; } // - 移動單張圖片的寬度 * index 回調函數 move(pic,"left",20,-index * lis[0].offsetWidth,setBtn); }
做左邊的點擊事件,實現
function Pre(){ //全局的索引值 減1 index --; if(index < 0 ) { index = len - 1; pic.style.left = -len * lis[0].offsetWidth + "px"; } //沒有使用回調函數 是為了做一個返回去的效果. move(pic,"left",20,-index * lis[0].offsetWidth); //按鈕背景跟隨 setBtn(); }
自動輪播,實現:
//自動輪播 function autoPlay(){ timer = setInterval(function(){ Next(); },3000); }
所有代碼實現:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <style type="text/css"> *{ margin: 0; padding: 0; } .slider{ width: 500px; height: 300px; border: 1px solid; margin: 50px auto; position: relative; /* overflow: hidden; */ } .slider .pic{ /* width: 500px; */ /* width: calc(500px*6); */ height: 300px; position: absolute; left: 0; } .slider .pic li{ width: 500px; height: 300px; list-style: none; float: left; } .slider .pic li img{ width: 100%; height: 100%; } .slider .btn{ width: 150px; height: 20px; position: relative; margin: 0 auto; top: 260px; } .slider .btn span{ float: left; width: 20px; height: 20px; background-color: #000000; color: #fff; border-radius:50%; font-size: 12px; text-align: center; line-height: 20px; margin: 0 5px; cursor: pointer; } .bigBtn{ width: 100%; height: 50px; position: absolute; top: 50%; margin-top: -25px; } .bigBtn div{ width: 50px; height: 50px; background-color: #000000; color: #fff; font-size: 30px; text-align: center; line-height: 50px; cursor: pointer; } .bigBtn div:nth-child(1){ float: left; } .bigBtn div:nth-child(2){ float: right; } .bg{ background-color: greenyellow !important; } #sliderBox{ margin: 0 auto; width: 500px; height: 300px; overflow: hidden; position: absolute; top: 0; left: 0; } </style> </head> <body> <div class="slider"> <div id="sliderBox"> <div class="pic"> <ul> <li><img src="img/pic1.jpg" ></li> <li><img src="img/pic2.jpg" ></li> <li><img src="img/pic3.jpg" ></li> <li><img src="img/pic4.jpg" ></li> <li><img src="img/pic5.jpg" ></li> <li><img src="img/pic1.jpg" ></li> </ul> </div> </div> <div class="btn"> <span>1</span> <span>2</span> <span>3</span> <span>4</span> <span>5</span> </div> <div class="bigBtn"> <div class="previous"><</div> <div class="next">></div> </div> </div> <script src="js/move.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> //獲取所有元素 let slider = document.querySelector(".slider") let lis = document.querySelectorAll("li"); let spanBtns = document.querySelectorAll(".btn span"); let previous = document.querySelector(".previous"); let next = document.querySelector(".next"); let pic = document.querySelector(".pic"); //設置元素的索引值 全局索引 var index = 0; //圖片數組的長度 4 let len = lis.length - 1 ; //設置初始pic長度. pic.style.width = (len + 2)*parseInt(getStyle(lis[0],"width"))+ "px"; //設置定時器 let timer = null; // 圓形按鈕點擊事件 使用的是let變量,即不會發生先循環完畢,再執行事件 for(let j = 0 ; j < len ; j++) { //spanBtns就是存圓形按鈕元素的數組. index是全局的一個值,用來作為索引值. spanBtns[j].onclick = function(){ index = j; //這里使用了一個封裝的移動函數. //第一個參數值是需要改變的元素,第二個是屬性 //第三個是步長. 第四個是目標位置. 第五個參數是回調函數. move(pic,"left",20,-index*lis[0].offsetWidth,function(){ setBtn(); }); } } function setBtn(){ if(index >= len) { index = 0; pic.style.left = 0; } for(var i = 0 ; i < len ; i++) { spanBtns[i].className = ""; } spanBtns[index].className = "bg"; } //onNext function Next(){ index ++; if(index > len) { index = 0; } // - 移動單張圖片的寬度 * index 回調函數 move(pic,"left",20,-index * lis[0].offsetWidth,setBtn); } function Pre(){ //全局的索引值 減1 index --; if(index < 0 ) { index = len - 1; pic.style.left = -len * lis[0].offsetWidth + "px"; } //沒有使用回調函數 是為了做一個返回去的效果. move(pic,"left",20,-index * lis[0].offsetWidth); //按鈕背景跟隨 setBtn(); } //綁定點擊事件 previous.onclick = Pre; next.onclick = Next; slider.onmouseover = function(){ clearInterval(timer); } slider.onmouseout = function(){ autoPlay(); } //自動輪播 function autoPlay(){ timer = setInterval(function(){ Next(); },3000); } setBtn(); autoPlay(); </script> </body> </html>
引用的js文件:
/* 封裝move函數 ele 要傳遞的元素 attr 屬性 --- 字符串 speed 速度 正負值 target 目標值(結束位置) callback 回調函數 --- 當這個函數執行完畢后,再去調用它 */ function move(ele, attr, speed, target, callback){ //獲取當前的位置 //從左往右進行移動 --- current<target speed //從右往左進行移動 --- current>target -speed var current = parseInt(getStyle(ele, attr)); // 810 > 800 if(current>target){ speed = -speed; } //定時器累加問題 --- 先清除再開啟 clearInterval(ele.timer); ele.timer = setInterval(function(){ //獲取元素的現在位置 var begin = parseInt(getStyle(ele, attr)); //步長 var step = begin + speed; //判斷當step>800, 讓step = 800 //從左往右進行移動 --- speed>0 正值 //從右往左進行移動 --- speed<0 負值 // -10 0 10 超過800直接變成 800 if(speed<0 && step<target || speed>0 && step>target){ step = target; } //賦值元素 ele.style[attr] = step + "px"; //讓元素到達目標值時停止 800px if(step == target){ clearInterval(ele.timer); //當move函數執行完畢后, 就執行它了 //當條件都滿足時才執行callback回調函數 callback && callback(); } },30) } //獲取元素的方式 --- 注意點:如果在IE瀏覽器下, 要指定默認的值, 如果不指定獲取的是auto function getStyle(obj, name){ if(window.getComputedStyle){ return getComputedStyle(obj, null)[name]; }else{ return obj.currentStyle[name]; } }
要移植使用的話,新建一個move.js 將最下面的代碼拷進去 放在js文件夾下。
類似這樣的目錄即可。
下次的博客一定會寫更好的。加油。