現在要自行因代碼實作一個輪播圖,主要具備下列功能
- 定時輪播
- 滑鼠移入暫停輪播,移出繼續正常輪播
- 點選左側按鈕,檢視上一張
- 點選右側按鈕,檢視下一張
- 導航欄地小圓點根據不同輪播圖,對應高亮
現在看一下實作地具體效果(找圖檔太麻煩,我直接把每張輪播圖設定不同顔色,友善辨認)
按照以往慣例,依舊是來捋一下思路:
首先看一下大思路:盒子設定溢出隐藏,設定7個 li 标簽用于表示輪播圖(首尾兩張是假圖,為了實作無縫輪播),父盒子相對定位,ul絕對定位,利用left屬性移動實作輪播。
看一下沒有設定溢出隐藏時的效果
功能實作 | 思路 |
---|---|
自動輪播 | 定時器實作 |
無縫輪播銜接 | 需要展示的是五張,準備7張,第一張和第六張一樣,第七張和第二張一樣(第二張其實就是肉眼見到的第一張),當輪播到第七張以後,無過渡直接跳到第二張,同樣地,輪播到第一張時,無過渡直接跳到 |
導航自動對應高亮 | 首先将目前的那張輪播圖序号,利用自定義屬性設定給父盒子,由此可以将對應的小圓點按照序号設定高亮 |
滑鼠移入暫停 | 注冊滑鼠移入事件,在事件函數中清除定時器 |
滑鼠移出按照原位置繼續輪播 | 擷取父盒子自定義屬性中記錄的序号,由此實作,注意不要重新再設定一個定時器 |
點選按鈕切換上下頁 | 依舊是需要擷取序号,下一張就序号就加一,上一張就減一 |
代碼展示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!-- <meta name="viewport" content="width=device-width, initial-scale=1.0"> -->
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
*{
margin: 0;
padding: 0;
}
.white{
background-color: #ccc;
}
.black{
background-color:black ;
}
#banner{
width: 400px;
height: 200px;
overflow: hidden;
margin: 100px auto;
position: relative;
}
ul{
position: absolute;
width: 3200px;
height: 200px;
list-style: none;
position: relative;
left: -400px;
}
ul>li{
box-sizing: border-box;
border: 1px solid #000;;
padding-top: 100px;
text-align: center;
width: 400px;
height: 200px;
background-color: rgb(128, 17, 17);
float: left;
}
ul>li:first-child {
background-color: rgb(108, 8, 117);
}
ul>li:nth-child(2) {
background-color: rgb(26, 131, 40);
}
ul>li:nth-child(3) {
background-color: rgb(129, 31, 64);
}
ul>li:nth-child(4) {
background-color: rgb(61, 39, 156);
}
ul>li:nth-child(5){
background-color: rgb(16, 92, 128);
}
ul>li:nth-child(6){
background-color: rgb(108, 8, 117);
}
ul>li:nth-child(7){
background-color: rgb(26, 131, 40);
}
#banner_item {
position: relative;
top: -150px;
width: 100px;
height: 3px;
margin: 0 auto;
}
ol {
list-style: none;
width:100px;
height: 3px;
}
ol>li {
width: 10px;
height: 10px;
border-radius: 50% 50%;
background-color: #cccc;
float: left;
margin-right: 10px;
}
#left_btn,
#right_btn {
width: 40px;
height:40px;
position:absolute;
background-color:rgba(65, 30, 30, 0.5);
font-size: 20px;
box-sizing: border-box;
}
#left_btn {
left: 0;
top:80px;
}
#right_btn{
padding-left: 20px;
right: 0;
top:80px;
}
</style>
</head>
<body>
<div id="banner">
<ul>
<!-- 用于做輪播圖 -->
<li>5</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>1</li>
</ul>
<div id="left_btn"><</div>
<div id="right_btn">></div>
</div>
<div id="banner_item">
<ol>
<!-- 用于做導航的小圓點 -->
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ol>
</div>
<script>
var ul=document.querySelector("#banner>ul");//擷取ul元素
// var first_lis=document.querySelectorAll("ul>li");//擷取ul的li元素僞數組
var second_lis=document.querySelectorAll("ol>li");//擷取ol的li元素
var banner=document.getElementById("banner");
console.log(first_lis[0].offsetWidth);
var step=first_lis[0].offsetWidth;// 每張輪播圖的寬度
var distance=0;//用于記錄每次移動地距離
var n=1;//用于記錄目前是哪一張輪播圖
function fn(){
banner.dataset.index=n;
console.log(n);
distance=n*step;
ul.style.left=-distance+"px";
// 實作導航高亮
for(var i=0;i<second_lis.length;i++){
second_lis[i].className="white";
// 實作排他,先全部不高亮
}
if(n>=6){
second_lis[0].className="black";
}else if(n==0){
second_lis[4].className="black";
}
else{
second_lis[n-1].className="black";
}
}
function timefn(){
ul.style.transition="none";
// 提前清除一下過渡效果
if(n<=-1){
n=5;
fn();
}else if(n>=7){
//當圖檔到達最後一張時,退回到第一張,實作無縫輪播
n=1;
fn();
}
else{
fn();
ul.style.transition="all 1s";
}
}
//自動輪播效果
var timeid=setInterval(function(){
timefn();
n++;
},1000);
//滑鼠移入,輪播暫停
var left=document.getElementById('left_btn');
var right=document.getElementById("right_btn");
banner.addEventListener("mouseenter",mouseFn);
function mouseFn(){
clearInterval(timeid);//清除定時器,輪播圖停止
//點選左邊按鈕,檢視上一張
var boot=0;
function toggle(){
n=banner.dataset.index;//擷取目前輪播圖地序号
if(boot<0){
--n;
timefn();
} else{
++n;;
timefn();
}
}
left.addEventListener("click",function(){
boot=-1;
toggle();
console.log("我現在是第"+banner.dataset.index+"張");
})
// //點選右邊按鈕,檢視下一張
right.addEventListener("click",function(){
boot=1;
toggle();
})
}
banner.addEventListener("mouseleave",function(){
clearInterval(timeid);
n=banner.dataset.index;
timeid=setInterval(function(){
timefn();
n++;
},1000);
})
// banner.addEventListener("mouseleave",function(){
// console.log(banner.dataset.index);
// })
</script>
</body>
</html>
總結:其實輪播圖有很多元件可以直接實作,這種原生的寫起來也比較麻煩,但是也算是加深了一下對定時器以及過渡等的了解,當然原生的寫法也不止這一種,有興趣也可以用其他方法實作一下。