天天看點

純js代碼實作輪播圖

現在要自行因代碼實作一個輪播圖,主要具備下列功能

  • 定時輪播
  • 滑鼠移入暫停輪播,移出繼續正常輪播
  • 點選左側按鈕,檢視上一張
  • 點選右側按鈕,檢視下一張
  • 導航欄地小圓點根據不同輪播圖,對應高亮

現在看一下實作地具體效果(找圖檔太麻煩,我直接把每張輪播圖設定不同顔色,友善辨認)

純js代碼實作輪播圖

按照以往慣例,依舊是來捋一下思路:

首先看一下大思路:盒子設定溢出隐藏,設定7個 li 标簽用于表示輪播圖(首尾兩張是假圖,為了實作無縫輪播),父盒子相對定位,ul絕對定位,利用left屬性移動實作輪播。

看一下沒有設定溢出隐藏時的效果

純js代碼實作輪播圖
功能實作 思路
自動輪播 定時器實作
無縫輪播銜接 需要展示的是五張,準備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">&lt</div>
 <div id="right_btn">&gt</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>
           

總結:其實輪播圖有很多元件可以直接實作,這種原生的寫起來也比較麻煩,但是也算是加深了一下對定時器以及過渡等的了解,當然原生的寫法也不止這一種,有興趣也可以用其他方法實作一下。