现在要自行因代码实现一个轮播图,主要具备下列功能

  • 定时轮播
  • 鼠标移入暂停轮播,移出继续正常轮播
  • 点击左侧按钮,查看上一张
  • 点击右侧按钮,查看下一张
  • 导航栏地小圆点根据不同轮播图,对应高亮

现在看一下实现地具体效果(找图片太麻烦,我直接把每张轮播图设置不同颜色,方便辨认)

javascript中写轮播图的代码 简单的轮播图js代码_轮播图


按照以往惯例,依旧是来捋一下思路:

首先看一下大思路:盒子设置溢出隐藏,设置7个 li 标签用于表示轮播图(首尾两张是假图,为了实现无缝轮播),父盒子相对定位,ul绝对定位,利用left属性移动实现轮播。看一下没有设置溢出隐藏时的效果

javascript中写轮播图的代码 简单的轮播图js代码_过渡_02

功能实现

思路

自动轮播

定时器实现

无缝轮播衔接

需要展示的是五张,准备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>

总结:其实轮播图有很多组件可以直接实现,这种原生的写起来也比较麻烦,但是也算是加深了一下对定时器以及过渡等的理解,当然原生的写法也不止这一种,有兴趣也可以用其他方法实现一下。