目的:通过CSS + jQuery的方式实现自动无缝轮播。

思路:把所有的轮播图片划分为三种状态,分别是准备轮播进入(enter)、在轮播中(current)、轮播结束后离开(leave),一张图片先是准备轮播,然后进入轮播,接着离开轮播进入到准备轮播的状态,等待下一次播送。

1.HTML结构

<div class="window3">
<div class="images3"><img alt="" src="./img/function-01.jpg" style="height:540px; width:960px" /> <img alt="" src="./img/git-01.jpg" style="height:540px; width:960px" /> <img alt="" src="./img/JQUERY-01.jpg" style="height:540px; width:960px" /> <img alt="" src="./img/内存-01.jpg" style="height:540px; width:960px" /> <img alt="" src="./img/数组-01.jpg" style="height:540px; width:960px" /></div>
</div>

2.CSS样式
确定轮播窗口尺寸和轮播图片的位置排列
在之前的博文中,我们的CSS使用的是display:flex搭配translateX()来实现轮播功能,但是在这里,因为实现思路改变了,我们需要根据状态的不同把图片划分到不同的区域,所以使用了position:absolute搭配translateX()。

.window3 {
    width: 960px;
    height: 540px;
    margin: 30px auto;
    overflow: hidden;
    border: 1px solid red;
}
.images3 {
    position: relative;
}
.images3 img {
    width: 100%;
    transition: all 0.5s;
    position: absolute;
    top: 0;
}

给图片添加状态
根据图片的状态的不同,划分到不同的区域。

.images3 img.current {
    left: 0;
    transform: translateX(0);
    z-index: 1;
}
.images3 img.leave {
    transform: translateX(-100%);
    z-index: 1;
}
.images3 img.enter {
    transform: translateX(100%)
}

3.添加JS
添加js控制元素样式的变化。

先给每一张图片划分状态

$('.images3  img:nth-child(1)').addClass('current')
$('.images3  img:nth-child(2)').addClass('enter')
$('.images3  img:nth-child(3)').addClass('enter')
$('.images3  img:nth-child(4)').addClass('enter')
$('.images3  img:nth-child(5)').addClass('enter')

设定每两秒自动轮播

//设定开始轮播的图片x
let m = 1

setInterval(() => {
    
    //加入判断,每当一轮轮播结束,都让轮播从第一张图片开始(重设x=1)
    if(m>5){
        m = m % 5
        if (m === 0){
            m = 5
        }
    }
    // 使用ES6插值法把n传进去
    $('.images3  img:nth-child(${m})').removeClass('current').addClass('leave')
        
        //one()表示只此一次,transitonend表示动画结束时
        .one('transitionend',(e) => {
            $(e.currentTarget).removeClass('leave').addClass('enter')
        })
    $('.images3  img:nth-child(${m+1})').removeClass('enter').addClass('current')
    m += 1
},2000)

这样我们就完成了一个无缝轮播了!

4.优化代码
把功能重复的代码封装成一个函数,让代码更简洁。

$('.images3  img:nth-child(1)').addClass('current')
$('.images3  img:nth-child(2)').addClass('enter')
$('.images3  img:nth-child(3)').addClass('enter')
$('.images3  img:nth-child(4)').addClass('enter')
$('.images3  img:nth-child(5)').addClass('enter')

// 优化后
functiont  imgsInit(){
    let n = 1
    $('.images3  img:nth-child(${n})').addClass('current')
        .siblings().addClass('enter')
}
if(x>5){
    x = x % 5
    if (x === 0){
        x = 5
    }
}

// 优化过后:
function x(m){
    if(m>5){
        m = m % 5
        if(m === 0){
            m = 5
        }
    }
}
//这段代码的主要功能是对一个jQuery对象添加/删除样式
$('.images3  img:nth-child(${x})').removeClass('current').addClass('leave')

// 优化过后:
function makeLeave($node){
    $node.removeClass('current').addClass('leave')
    return $node
}

//其他的依次类推
function makeEnter($node){
    $node.removeClass('leave').addClass('enter')
    return $node
}
function makeCurrent($node){
    $node.removeClass('enter').addClass('current')
    return $node
}

我们的主要代码就变成了:

let m = 1  
setInterval(() => {
	makeLeave($('.images3  img:nth-child(${x(m)})'))
		.one('transitionend',(e) => {
			makeEnter($(e.currentTarget))
		})
	makeCurrent($('.images3  img:nth-child(${x(m+1)})'))
	m += 1
},2000)

还可以优化:
优化原则:只要还有代码重复,就有优化的可能

$('.images3  img:nth-child(${x(m)})')

这段代码的作用也是获取根据m的值来获取一个jQuery对象,可以优化成:

function getImages(m){
    return $('.images3  img:nth-child(${x(m)})')
}

最后,主代码就精简成了:

let m = 1  
imgsInit()
setInterval(() => {
    makeLeave(getImages(m))
        .one('transitionend',(e) => {
            makeEnter($(e.currentTarget))
        })
    makeCurrent(getImages(m+1))
    m += 1
},2000)

无缝轮播知识点总结:
理解状态机(每隔一段时间,根据图片的样式划分到不同的状态)
CSS需要position: absolute和 translateX()的配合
setInterval()的使用
代码的抽象能力