首頁 > 軟體

JS原生手寫輪播圖效果

2022-08-04 14:01:43

本文範例為大家分享了JS原生手寫輪播圖效果的具體程式碼,供大家參考,具體內容如下

前言

本系列主要整理前端面試中需要掌握的知識點。本節介紹如何用原生JS手寫輪播圖。

一、手寫初級輪播圖

功能分析

1、初級輪播圖功能介紹:①左右兩端有左右按鈕;②下方有小球指示當前是第幾張圖片;③無切換效果;④如果兩秒中使用者沒有點選輪播圖,則從左到右自動播放。
2、功能展示:

實現思路

HTML中需要包括一個大盒子class=wrap,為輪播圖的盒子。一張一張的圖片可以用無序列表儲存,左右按鈕使用button,下方圓點也用無序列表,併為每一個圓點設定計數器data-index。HTML的程式碼如下:

<div class="wrap">
    <ul class="list">
        <li class="item active">0</li>
        <li class="item">1</li>
        <li class="item">2</li>
        <li class="item">3</li>
        <li class="item">4</li>
    </ul>
    <ul class="pointList">
        <li class="point active" data-index="0"></li>
        <li class="point" data-index="1"></li>
        <li class="point" data-index="2"></li>
        <li class="point" data-index="3"></li>
        <li class="point" data-index="4"></li>
    </ul>
    <button class="btn" id="leftBtn"><</button>
    <button class="btn" id="rightBtn">></button>
</div>

CSS中,給wrap盒子一個寬高。list盒子和它同寬同高。每一張圖片充滿盒子,並且都用絕對定位固定在wrap盒子裡,讓他們有不同的顏色,初始透明度都是0即全透明,並且,哪個需要展示,哪個的z-index就變大,並且透明度改為1。左右按鈕直接使用定位固定在左右兩端,小圓點內部使用浮動,再用定位固定在下端。

* {
    margin: 0;
    padding: 0;
    list-style: none;
}
/* 輪播圖大盒子 */
.wrap {
    width: 800px;
    height: 400px;
    position: relative;
}
.list{
    width: 800px;
    height: 400px;
    position: relative;
}
/* 每一張圖片 */
.item {
    width: 100%;
    height: 100%;
    position: absolute;
    left: 0;
    opacity: 0;
}
/* 不同的圖片不同的顏色 */
.item:nth-child(1){
    background-color: skyblue;
}
.item:nth-child(2){
    background-color: yellowgreen
}
.item:nth-child(3){
    background-color: rebeccapurple;
}
.item:nth-child(4){
    background-color: pink;
}
.item:nth-child(5){
    background-color: orange;
}
.item.active {
    opacity: 1;
    z-index: 20;
}
/* 按鈕的設定 */
.btn {
    width: 50px;
    height: 100px;
    position: absolute;
    top: 50%;
    transform:translate(0,-50%);
    z-index: 200;
}
#leftBtn {
    left: 0;
}
#rightBtn {
    right: 0;
}
/* 小圓點的設定 */
.pointList {
    height: 10px;
    position: absolute;
    bottom: 20px;
    right: 20px;
    z-index: 200;
}
.point {
    width: 10px;
    height: 10px;
    background-color: antiquewhite;
    float: left;
    margin-left: 8px;
    border-style: solid;
    border-radius: 100%;
    border-width: 2px;
    border-color: slategray;
}
.point.active {
    background-color: cadetblue;
}

JS的實現思路如下:

1.獲取元素:包括圖片、圓點、按鈕、輪播圖大盒子

2.需要一個變數index記錄當前圖片的索引,並且在每次點選的時候要先將樣式清空,再根據索引重新賦值(排他思想)

3.點選左右按鈕的時候,只需要判斷是否為第一張或者最後一張,然後進行+1 -1操作即可。

4.點選小圓點時,需要記錄點選的圓點的data-index,賦值給Index,然後再執行

5.定義計時器,當滑鼠在wrap內,就取消計時,不在wrap內,就開始計時,兩秒以後自動播放。

JS整體程式碼:

// 輪播圖圖片
let items = document.querySelectorAll('.item')
// 下方圓點
let points = document.querySelectorAll('.point')
// 左右按鈕
let left = document.querySelector('#leftBtn')
let right = document.querySelector('#rightBtn')
// 輪播圖盒子
let wrap = document.querySelector('.wrap')
// 記錄當前展示的是第幾張圖片
var index = 0;
// 移除所有的active
var removeActive = function(){
    for(var i=0;i<items.length;i++){
        items[i].className = "item"
    }
    for(var i=0;i<points.length;i++){
        points[i].className = "point"
    }
}
// 為當前index加入active
var setActive = function(){
    removeActive();
    items[index].className = "item active";
    points[index].className = "point active";
}
// 點選左右按鈕觸發修改index的事件
var goleft = function(){
    if(index==0){
        index = 4;
    }else{
        index--;
    }
    setActive();
}
var goright = function(){
    if(index==4){
        index = 0;
    }else{
        index++;
    }
    setActive();
}        

left.addEventListener('click',function(){
    goleft();
})
right.addEventListener('click',function(){
    goright();
})
// 點選小圓點
for(var i=0;i<points.length;i++){
    points[i].addEventListener('click',function(){
        var pointIndex = this.getAttribute('data-index')
        index = pointIndex;
        setActive();
    })
}
//計時器
var timer
function play() {
    timer = setInterval(() => {
        goright()
    }, 2000)
}
play()
//移入清除計時器r
wrap.onmouseover = function () {
    clearInterval(timer)
}
//移出啟動計時器
wrap.onmouseleave = function () {
    play()
}

二、優化輪播圖

增加的功能

1、滑鼠經過輪播圖再出現左右按鈕;
2、圖片有左右捲動的效果,看起來是連續的。
3、功能展示:

實現要點

1.所有的圖片不應該疊放,而是應該拼接起來,這個可以在CSS中修改。

2.因為是連續播放,需要拷貝第一張圖片到輪播圖的最後,這樣最後一張到第一張的效果才會連續。

3.連續移動的效果是通過緩動動畫實現的:移動的步長由大到小,最後慢慢停下來。

最後完整的程式碼如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="animate.js"></script>
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            list-style: none;
        }
        .wrap {
            width: 800px;
            height: 400px;
            background-color: pink;
            position: relative;
            overflow: hidden;
        }
        .list{
            width: 600%;
            height: 400px;
            position: absolute;
            left:0;
        }
        .item {
            width: 800px;
            height: 100%;
            float: left;
        }
        .item:nth-child(1){
            background-color: skyblue;
        }
        .item:nth-child(2){
            background-color: yellowgreen
        }
        .item:nth-child(3){
            background-color: rebeccapurple;
        }
        .item:nth-child(4){
            background-color: pink;
        }
        .item:nth-child(5){
            background-color: orange;
        }
        .item:nth-child(6){
            background-color: skyblue;
        }
        /* .item.active {
            opacity: 1;
            z-index: 20;
        } */
        .btn {
            width: 50px;
            height: 100px;
            position: absolute;
            top: 50%;
            transform:translate(0,-50%);
            z-index: 200;
            display: none;
        }
        #leftBtn {
            left: 0;
        }
        #rightBtn {
            right: 0;
        }

        .pointList {
            height: 10px;
            position: absolute;
            bottom: 20px;
            right: 20px;
            z-index: 200;
        }
        .point {
            width: 10px;
            height: 10px;
            background-color: antiquewhite;
            float: left;
            margin-left: 8px;
            border-style: solid;
            border-radius: 100%;
            border-width: 2px;
            border-color: slategray;
        }
        .point.active {
            background-color: cadetblue;
        }
    </style>
</head>
<body>
    <div class="wrap">
        <ul class="list">
            <li class="item">0</li>
            <li class="item">1</li>
            <li class="item">2</li>
            <li class="item">3</li>
            <li class="item">4</li>
        </ul>
        <ul class="pointList">
            <li class="point active" data-index="0"></li>
            <li class="point" data-index="1"></li>
            <li class="point" data-index="2"></li>
            <li class="point" data-index="3"></li>
            <li class="point" data-index="4"></li>
        </ul>
        <button class="btn" id="leftBtn"><</button>
        <button class="btn" id="rightBtn">></button>
    </div>
    <script>
        /* 1.獲取元素 */
        // 整個輪播圖範圍
        let wrap = document.querySelector('.wrap')
        let ul = document.querySelector('.list')
        // 輪播圖圖片
        let items = document.querySelectorAll('.item')
        // 下方圓點
        let points = document.querySelectorAll('.point')
        // 左右按鈕
        let left = document.querySelector('#leftBtn')
        let right = document.querySelector('#rightBtn')
        var focusWidth = wrap.offsetWidth;
        /* 2.滑鼠經過輪播圖,左右按鈕出現,離開則按鈕消失 */
        wrap.addEventListener('mouseenter',function(){
            left.style.display = 'block'
            right.style.display = 'block'
        });
        wrap.addEventListener('mouseleave',function(){
            left.style.display = 'none'
            right.style.display = 'none'
        })
         /* 3.克隆第一張圖片放到ul最後面 */
         var first = ul.children[0].cloneNode(true)
         ul.appendChild(first)
         items = document.querySelectorAll('.item')

        /* 4. 記錄當前展示的是第幾張圖片 */
        var index = 0;
        /* 5.移除所有的active */
        var removeActive = function(){
            for(var i=0;i<items.length;i++){
                items[i].className = "item"
            }
            for(var i=0;i<points.length;i++){
                points[i].className = "point"
            }
        }
        /* 6.為當前index加入active */
        var setActive = function(){
            removeActive();
            // ul.style.left = -(index*focusWidth) + 'px'
            animate(ul, -index * focusWidth);
            // console.log(index);
            // console.log(ul.style.left);
            if(index==5) {
                points[0].className = "point active";
            }else{
                points[index].className = "point active";
            }
        }
        /* 7.點選左右按鈕觸發修改index的事件 */
        var goleft = function(){
            if(index==0){
                index = 5;
                ul.style.left = "-4000px";
            }
            index--;
            setActive();
        }
        var goright = function(){
            if(index==5){
                index = 0;
                ul.style.left = 0;
            }
            index++;
            setActive();
        }        

        left.addEventListener('click',function(){
            goleft();
        })
        right.addEventListener('click',function(){
            goright();
        })
        /* 8.點選圓點更改輪播圖 */
        for(var i=0;i<points.length;i++){
            points[i].addEventListener('click',function(){
                var pointIndex = this.getAttribute('data-index')
                index = pointIndex;
                setActive();
            })
        }
        /* 9.計時器 */
        var timer
        function play() {
            timer = setInterval(() => {
                goright()
            }, 2000)
        }
        play()
        //移入清除計時器r
        wrap.onmouseover = function () {
            clearInterval(timer)
        }
        //移出啟動計時器
        wrap.onmouseleave = function () {
            play()
        }
        
    </script>
</body>
</html>

三、繼續優化思路

1、下方小圓點根據圖片個數自動生成;
2、利用節流控制左右切換的速度。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com