轮播原理简述
- 假设有三张图,一字排开,用一个div包起来。
- 再来一个 div ,宽高和每幅图宽高一样,加overflow :hidden,超过此 div 宽高的图,都看不见。例如下图只能看见 2 ,而看不到 1 和 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 变成红色)。
说明:
- setInterval() 方法重复调用一个函数或执行一个代码段,在每次调用之间具有固定的时间延迟。
- .eq() 方法是 jQuery 中的一种遍历方法,这里用来找出第 n % size 张图。
- .trigger() 触发器可以出发各种事件,比如:click,submit。
思考1:鼠标悬停怎么做?
解决方案:用 mouseenter 和 mouseleave
当鼠标进入图片的时候,把计时器清除,当鼠标移除的时候,计时器继续。
- 给 setInterval 一个名字,叫 timerId。
var timerId = setInterval(()=> {
n++;
allButtons.eq(n%size)
.trigger('click')
.addClass('red')
.siblings('.red')
.removeClass('red');
},2000);
复制代码
- 鼠标进入图片,清除计时器
$('.window').on('mouseenter',function(){
window.clearInterval(timerId);
})
复制代码
- 鼠标移出,恢复计时。
$('.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');
}
复制代码
小结
- 点击 button 切换图片(transform & margin-left)
- 代码优化——多张图无限轮播
- 自动轮播
- 鼠标悬停
- 点击后继续轮播
- 封装函数 & 优化代码