JavaScript實現輪播圖思路 + html/css + js源碼
- 整個輪播圖的效果是通過js代碼,操作dom, 拿到html我們需要的元素,控制整個ul的距離瀏覽器左邊的位置,讓排好的圖片依次出現在相框中,不在相框中的元素會被css中的 overflow : hidden 隱藏掉, 其次,圖片是經過處理的 ,正好和我們的相關等寬等高!
- 動態的創建元素,下面我們會動態創建li,並通過css把它修飾成小按鈕格式,其次給小按鈕添加點擊事件,鼠標經過,離開事件,動態的實現圖片的移動, 其實就是根據不同的參數,移動 ul的left值
- 最后添加定時器,在回調函數的位置讓他每隔一定的時間就調用一次點擊左邊按鈕的事件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
* {
padding: 0;
margin: 0;
list-style: none;
border: 0;
}
.all {
width: 500px;
height: 200px;
padding: 7px;
border: 1px solid #ccc;
margin: 100px auto;
position: relative;
}
.screen {
width: 500px;
height: 200px;
/* overflow: hidden;*/
position: relative;
}
.screen li {
width: 500px;
height: 200px;
overflow: hidden;
float: left;
}
.screen ul {
position: absolute;
left: 0;
top: 0px;
width: 3000px;
}
.all ol {
position: absolute;
right: 10px;
bottom: 10px;
line-height: 20px;
text-align: center;
}
.all ol li {
float: left;
width: 20px;
height: 20px;
background: #fff;
border: 1px solid #ccc;
margin-left: 10px;
cursor: pointer;
}
.all ol li.current {
background: #DB192A;
}
#arr {
display: none;
}
#arr span {
width: 40px;
height: 40px;
position: absolute;
left: 5px;
top: 50%;
margin-top: -20px;
background: #000;
cursor: pointer;
line-height: 40px;
text-align: center;
font-weight: bold;
font-family: '黑體';
font-size: 30px;
color: #fff; opacity: 0.3;
border: 1px solid #fff;
}
#arr #right {
right: 5px;
left: auto;
}
</style>
</head>
<body>
<div class="all" id='box'>
<div class="screen"><!--相框-->
<ul>
<li><img src="images/1.jpg" width="500" height="200"/></li>
<li><img src="images/2.jpg" width="500" height="200"/></li>
<li><img src="images/3.jpg" width="500" height="200"/></li>
<li><img src="images/4.jpg" width="500" height="200"/></li>
<li><img src="images/5.jpg" width="500" height="200"/></li>
</ul>
<ol><!-- ol 里面存放的是按鈕, 按鈕的個數,就是上面ul子元素的個數-->
</ol>
</div>
<div id="arr"><span id="left"><</span><span id="right">></span></div>
</div>
</body>
</html>
上面是html/css搭起來架子,簡單說一下
- body里面有一個直接子div,我們叫他box,它是整個輪播圖的父盒子
1 對box的css相關css樣式調整, 給定了寬高,讓他把輪播圖需要的空間撐起來, 2. 設置了內邊距,讓他在原有寬高不變的情況下,四周擴展一些,美觀 ; 3. 初始情況下,這個盒子貼着瀏覽器的左上角對齊,我們給他設置外邊距, 上下100px ,左右自動, 意思是居中對齊 4. 添加相對定位, 因為box里面的小按鈕要脫離文檔流,用定位移動到相框指定的位置, 如果不加相對定位, box就限制不住它里面的子元素,
- box又有兩個直接元素div
box 的第一個直接子元素class=screen , screen的寬高和box一樣,里面放着個無序列表,無序列表里面是輪播圖的圖片, 每一個li,都給定和圖片一樣大小的寬高,添加浮動,讓它們排成一排,給li添加overflow , 屬性,防止圖片太大了,把多出去的部分切掉,
screen的第二個直接子元素是個ol列表,一會我們要通過js動態的生成和 ul里面的li相同數目的li標簽,把他們的樣式改成按鈕, 需要絕對定位,因此我們設置screen為相對對位
box的第二個直接子元素是一個div叫arr,默認它dispaly:none 隱藏 ,arr里面是輪播圖的左右兩個箭頭,讓他相對於box 進行絕對定位
js代碼:
<script>
// 獲取全部需要的元素
var box = document.getElementById("box");
var screen = box.children[0];
var ulObj = screen.children[0];
var liList = ulObj.children;
var olObj = screen.children[1];
var arr = document.getElementById("arr");
var width = screen.offsetWidth; // 相框的寬
var index = 0; // 默認小按鈕的索引從零開始
var timeId;
// 動態的生成和li數量相等的 小按鈕
for (var i = 0; i < liList.length; i++) {
console.log(i);
var liObj = document.createElement("li");
// 添加下標
liObj.innerHTML = (i + 1);
// 添加到ol里面
olObj.appendChild(liObj);
// 給liObj添加屬性,存儲下標
liObj.setAttribute("index", i);
console.log("index===" + liObj.getAttribute("index"));
// 給小按鈕添加鼠標經過事件
liObj.onmouseover = function () {
for (var i = 0; i < olObj.children.length; i++) { // 排他去除所有按鈕的 點亮狀態
olObj.children[i].className = "";
}
this.className = "current"; // 設置當前的小按鈕點亮
// 移動, 將圖片移動到當前小按鈕下標的位置
// 設置 index 的值,為當前小按鈕的下標值
// index= liObj.getAttribute("index"); 不能這樣寫,因為一打開瀏覽器,js其實就執行完了, 這個屬性,事件都已經存在下來了,
// 於是我們在這里面只有 通過this,才能定位到當前的 小按鈕
index = this.getAttribute("index");
console.log(index);
animate(ulObj, -width * index);
};
liObj.onmouseout = function () {
this.className = "";
}
}
// 默認選中第一按鈕
olObj.children[0].className = "current";
// 鼠標移動到 box上面 顯示那兩個按鈕
document.getElementById("box").onmouseover = function () {
clearInterval(timeId);
document.getElementById("arr").style.display = "block";
};
// 鼠標離開box,干掉 arr 的顯示
document.getElementById("box").onmouseout = function () {
timeId = setInterval(rightHandler, 1000);
document.getElementById("arr").style.display = "";
}
// 無縫連接需要我們第一個輪播圖和最后一份完全相同,於是我們 克隆
// var liNode = liList.children[0].cloneNode(true);
var liNode = ulObj.children[0].cloneNode(true);
// 添加到 ul 尾部
ulObj.appendChild(liNode);
// 給做左邊的小按鈕綁定點擊事件
document.getElementById("right").onclick = rightHandler;
function rightHandler() {
console.log("index===" + index);
console.log("width===" + width);
index++; // 因為第一個index==0 , 所以想移動就得 ++
console.log("olObj.children.length-1== " + olObj.children.length);
if (index === olObj.children.length) { // 這是最后一個
// index==5 我們要重置
index = 0;
// 到第六張圖片的時候,我們應該把第五個小按鈕的點亮狀態給第一個小按鈕
olObj.children[olObj.children.length - 1].className = "";
olObj.children[0].className = "current";
// 整排圖片一次性全部歸位,准備重來
ulObj.style.left = 0 + "px";
} else {
// 1-4 正常移動圖片
animate(ulObj, -width * index);
for (var i = 0; i < olObj.children.length; i++) { // 排他干掉所有的 點亮的小按鈕
// console.log("執行了!!! i== "+i);
olObj.children[i].className = "";
}
// 設置 當前圖片對應的小按鈕點亮
olObj.children[index].className = "current";
}
}
// 點擊右邊的按鈕
document.getElementById("left").onclick = function () {
// 點擊右邊的小按鈕,整個圖片往左動,
// 點擊左邊的按鈕,整個圖片往右動--正數
console.log("left");
console.log("index==" + index);
// 如果是第一個,那么一次性移動到第六張圖片,在往右移動
if (index === 0) {
index = olObj.children.length;
ulObj.style.left = -width * index + "px";
}
index--;
console.log("index==" + index);
animate(ulObj, -width * index);
// 思考: 為什么我的圖片無論往左還是往右移動在 nimate里面都是負數呢? 看上面的最近的if判斷,當判斷為0
// 這時我們將圖片一次性的移動到了第六張的位置,往右動,遠離瀏覽器 -index*width
// 我們再次點擊 往右移動,就是希望,整個div 離瀏覽器的左邊遠一些,是往右動 就是讓left = -index*width 大一點 ,正好index--了 那么他們的絕對值就會變大
}
// 添加自動播放的效果-- 就是隔一段時間調用一次向左移動的函數
timeId = setInterval(rightHandler, 1000);
// 鼠標進入暫停--- 給 box 添加鼠標進入事件, 清除定時器
// 鼠標離開繼續動,就是給box 添加鼠標離開事件
function animate(element, target) {
clearInterval(element.timeId);
// element 點 timeId 是給 element 添加了一個屬性, 用來存 id , 以后觸發定時器,得到的id復寫上一個id, 這樣 定時器的時間就不會被改變
element.timeId = window.setInterval(function () {
// 獲取div的位置
var current = element.offsetLeft;
// div每次移動的 像素
var step = 10;
step = current < target ? step : -step; // 指明從左向右,還是反向
// 每次移動后的距離
current += step;
if ((Math.abs(target - current)) > Math.abs(step)) {
// 設置目標位置
element.style.left = current + "px";
} else {
window.clearInterval(element.timeId);
// if條件不成立.直接到達目標
element.style.left = target + "px";
}
}, 20);
}
</script>