1. 程式人生 > >[JavaScript]使用jQuery實現無縫輪播

[JavaScript]使用jQuery實現無縫輪播

方式 child margin blog turn use leave 分享 不同的

代碼鏈接:我的GitHub

項目預覽:預覽

目的:通過CSS + jQuery的方式實現自動無縫輪播。

上一篇博文總結了使用jQuery實現輪播,雖然是自動輪播,但是這個輪播有個不足之處:

技術分享圖片

技術分享圖片

技術分享圖片

他會在輪播結束的時候往左跳,跳回輪播開始的地方,這樣就顯得輪播效果很突兀,過渡不自然。

怎麽把他變成像下面這樣的無縫輪播,輪播結束的時候繼續往右跳,繼續下一輪播放呢?:

技術分享圖片

思路:把所有的輪播圖片劃分為三種狀態,分別是準備輪播進入(enter)、在輪播中(current)、輪播結束後離開(leave),一張圖片先是準備輪播,然後進入輪播,接著離開輪播進入到準備輪播的狀態,等待下一次播送。

技術分享圖片

1.HTML結構

<div class="window3">
    <div class="images3">
        <img src="./img/function-01.jpg"  width=960 height=540>
        <img src="./img/git-01.jpg"  width=960 height=540 >
        <img src="./img/JQUERY-01.jpg"  width=960 height=540>
        <img src="./img/內存-01.jpg"  width=960 height=540>
        <img src="./img/數組-01.jpg"  width=960 height=540>
    </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: absolutetranslateX()的配合
  • setInterval()的使用
  • 代碼的抽象能力

[JavaScript]使用jQuery實現無縫輪播