需求:實現輪播圖,圖片無縫切換,自動播放。
實現效果:


思考一下:在圖片列表后面多加一張圖片,這張圖片是第一張圖片(為了確保無縫銜接)。圖片就是平鋪放在一個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文件夾下。
類似這樣的目錄即可。
下次的博客一定會寫更好的。加油。
