轮播原理简述

  1. 假设有三张图,一字排开,用一个div包起来。
  2. 再来一个 div ,宽高和每幅图宽高一样,加overflow :hidden,超过此 div 宽高的图,都看不见。例如下图只能看见 2 ,而看不到 1 和 3 。
  3. 通过 margin-left 或者 transform 等属性来更改展示的图片,切换看到图 1 或者图 3。



1. 点击按钮切换图片



HTML

<!DOCTYPE html>
<html>
 <head> 
  <script src="//code.jquery.com/jquery-2.1.1.min.js"></script> 
  <meta charset="utf-8" /> 
  <title>JS Bin</title> 
 </head> 
 <body> 
  <div class="window"> 
   <div class="images" id="images"> 
    <img src="https://tympanus.net/Freebies/Cardio/img/team/team-cover2.jpg" alt="" /> 
    <img src="https://tympanus.net/Freebies/Cardio/img/team/team-cover1.jpg" alt="" /> 
    <img src="https://tympanus.net/Freebies/Cardio/img/team/team-cover3.jpg" alt="" /> 
   </div> 
  </div> 
  <button id="p1">1</button> 
  <button id="p2">2</button> 
  <button id="p3">3</button>  
 </body>
</html>
复制代码

CSS

.images {
	display: flex;
	align-items: flex-start;
	transition: transform 0.5s;
	/* 图片切换在 0.5s 内完成,以免切换速度过快或者过慢,用户不适 */
}

.window {
	width: 370px; /* 以上三张图片的宽为:370px */
	overflow: hidden;
}
复制代码

JavaScript (transform 实现)

var p1 = document.getElementById('p1');
var p2 = document.getElementById('p2');
var p3 = document.getElementById('p3');
var images = document.getElementById('images');

$(p1).on('click', function() {
    $(images).css({
        transform: 'translateX(0)'
        // 水平方向移动 0 px ,此时正显示的是第一张图
    })
})

$(p2).on('click', function() {
    $(images).css({
        transform: 'translateX(-370px)'
        // 水平方向移动 -370 px ,一张图的宽度
    })
})

$(p3).on('click', function() {
    $(images).css({
        transform: 'translateX(-740px)'
        // 水平方向移动 --740 px,前两张图的宽度
    })
})
复制代码

获取 3 个 button 的 id ,为 3 个 button 添加点击事件,点击后,给 id 为 images 的 div 添加 CSS 样式 transform ,达到切换图片、实现轮播的效果。

JavaScript (margin-left 实现)

var p1 = document.getElementById('p1');
var p2 = document.getElementById('p2');
var p3 = document.getElementById('p3');
var images = document.getElementById('images');

$(p1).on('click', function() {
    $(images).css({
        'margin-left': 0
    })
})

$(p2).on('click', function() {
    $(images).css({
        'margin-left': '-370px'
    })
})

$(p3).on('click', function() {
    $(images).css({
        'margin-left': '-740px'
    })
})
复制代码

注意 :margin-left 有 - 要用 ' ' 进行包裹。

代码优化 —— 无限张图轮播怎么办?

假如现在有 100 张图要轮播,难道要 var p1 = document.getElementById('p1'); 一百次? 添加 $(p1).on('click', function(){}) 一百次?显然上面的代码只顾着实现了功能,没有考虑代码的可维护性和拓展性。

修改 HTML 代码,把 button 放到一个小组里。只需要给“小组长” id 即可, 不需要给 button 组员每人一个 id 。

<span id="buttons">
    <button>1</button>
    <button>2</button>
    <button>3</button>
</span>
复制代码

修改 JavaScript 代码,获取所有 button 并添加点击事件,ev.currentTarget 指向添加监听事件的对象,.index( ) 获取点击 button 的索引,移动的距离 npx 为索引 * 图片宽度。

var allButtons = $('#buttons > button');
for(let i = 0;i < allButtons.length;i++){
  $(allButtons[i]).on('click',function(ev){
    var index = $(ev.currentTarget).index(); 
    var npx = index * -370;
    $('#images').css({
      transform:'translateX(' + npx + 'px)'
    });
  });
}
复制代码

现在无论实现多少张图的轮播,只需要以上几行代码轻松实现。

2. 自动轮播



自动轮播,就是让浏览器帮我们以相同时间间隔按顺序点击切换图片按钮。
为了使 gif 图录制出来的效果明显,我给选中的按钮加了黑色背景色。

CSS

.red{
      background: #000;
      color:red;
    }
复制代码

JavaScript

var allButtons = $('#buttons > button');
for(let i = 0;i<allButtons.length;i++){
  $(allButtons[i]).on('click',function(ev){
    var index = $(ev.currentTarget).index();
    var npx = index*-370;
    $('#images').css({
      transform:'translateX('+ npx +'px)'
    });
  });
}

var n = 0;
var size = allButtons.length;
setInterval(()=> {
  n++;
  allButtons.eq(n%size)
            .trigger('click')
            .addClass('red')
            .siblings('.red')
            .removeClass('red');
},3000);
复制代码

思路

利用 n 做计数器,找到要切换的第 n 个 button ,s 秒后触发第 n 个 button 的点击事件(切换图片完成),给所有的 button 加上 red 的属性,给当前 button 的兄弟元素移除 red 属性(对应图片的 button 变成红色)。

说明

  1. setInterval() 方法重复调用一个函数或执行一个代码段,在每次调用之间具有固定的时间延迟。
  2. .eq() 方法是 jQuery 中的一种遍历方法,这里用来找出第 n % size 张图。
  3. .trigger() 触发器可以出发各种事件,比如:click,submit。

思考1:鼠标悬停怎么做?

解决方案:用 mouseenter 和 mouseleave

当鼠标进入图片的时候,把计时器清除,当鼠标移除的时候,计时器继续。

  1. 给 setInterval 一个名字,叫 timerId。
var timerId = setInterval(()=> {
  n++;
  allButtons.eq(n%size)
            .trigger('click')
            .addClass('red')
            .siblings('.red')
            .removeClass('red');
},2000);
复制代码
  1. 鼠标进入图片,清除计时器
$('.window').on('mouseenter',function(){
  window.clearInterval(timerId);
})
复制代码
  1. 鼠标移出,恢复计时。
$('.window').on('mouseleave',function(){
  timerId = setInterval(()=> {
  n++;
  allButtons.eq(n%size)
            .trigger('click')
            .addClass('red')
            .siblings('.red')
            .removeClass('red');
},2000)
})
复制代码

思考2:点击第 n 个图片的 button ,从第 n 张图片开始轮播怎么办?

var allButtons = $('#buttons > button');
for(let i = 0;i<allButtons.length;i++){
  $(allButtons[i]).on('click',function(ev){
    var index = $(ev.currentTarget).index();
    var npx = index*-370;
    $('#images').css({
      transform:'translateX('+ npx +'px)'
    });
    n = index;
    allButtons.eq(n)
            .addClass('red')
            .siblings('.red')
            .removeClass('red');
  });
}
复制代码

记录被点击的是哪个 button,将 button 的 index 赋值给 n,遍历寻找到后添加 red 属性,并移除该元素兄弟的 red 属性。

代码优化

封装函数

function activeButton($button){
  $button.addClass('red')
         .siblings('.red')
         .removeClass('red');
         
}
复制代码
function playSlide(index){
  allButtons.eq(index).trigger('click');
}
复制代码
function setTimer(){
  return setInterval(()=> {
  n++;
  playSlide(n%size);
},2000)
}
复制代码

完整代码

var allButtons = $('#buttons > button');

for(let i = 0;i<allButtons.length;i++){
  $(allButtons[i]).on('click',function(ev){
    var index = $(ev.currentTarget).index();
    var npx = index*-370;
    $('#images').css({
      transform:'translateX('+ npx +'px)'
    });
    n = index;
    activeButton(allButtons.eq(n))
  });
}

var n = 0;
var size = allButtons.length;
var timerId = setTimer();

$('.window').on('mouseenter',function(){
  window.clearInterval(timerId);
})

$('.window').on('mouseleave',function(){
  timerId = setTimer();
})

function setTimer(){
  return setInterval(()=> {
  n++;
  playSlide(n%size);
},2000)
}

function playSlide(index){
  allButtons.eq(index).trigger('click');
}

function activeButton($button){
  $button.addClass('red')
         .siblings('.red')
         .removeClass('red');
         
}
复制代码

小结

  1. 点击 button 切换图片(transform & margin-left)
  2. 代码优化——多张图无限轮播
  3. 自动轮播
  4. 鼠标悬停
  5. 点击后继续轮播
  6. 封装函数 & 优化代码
快动手写个轮播吧~