目录
1. 轮播图基本形状

2. 核心代码
2.1 动画函数

2.2 核心代码
-  用到的变量 
  
-  克隆第一张图片 
  
-  根据图片个数创建小圆点 
  
-  右按钮点击事件 
  
-  左按钮点击事件 
  
-  自动播放功能 
  
3. 源代码
3.1 swiper.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="animate.js"></script>
    <script src="swiper.js"></script>
    <style>
        .swiper {
            position: relative;
            width: 721px;
            height: 455px;
            overflow: hidden;
            margin: 100px auto;
        }
        .swiper ul {
            position: absolute;
            top: 0;
            left: 0;
            list-style: none;
            margin: 0;
            padding: 0;
            width: 5000px;
        }
        ul li {
            float: left;
        }
        ol {
            padding: 0;
            margin: 0;
            list-style: none;
            position: absolute;
            bottom: 30px;
            left: 50%;
            transform: translateX(-50%);
        }
        
        ol li {
            width: 10px;
            height: 10px;
            border-radius: 50%;
            background-color: #fff;
            float: left;
            margin-right: 10px;
            cursor: pointer;
        }
        .arrow-l ,.arrow-r {
            position: absolute;
            width: 30px;
            height: 30px;
            background-color: #000;
            opacity: .3;
        }
        .arrow-l a ,.arrow-r a {
            display: block;
            width: 100%;
            height: 100%;
            color: white;
            font-weight: bold;
            text-decoration: none;
            text-align: center;
            line-height: 26px;
        }
        .arrow-l {
            left: 0;
            top: 50%;
            transform: translateY(-50%);
        }
        .arrow-r {
             right: 0;
             top: 50%;
             transform: translateY(-50%);
         }
        ol .current {
            background-color: orange;
        }
    </style>
</head>
<body>
    <div class="swiper">
        <ul>
            <li><a href="javascript:"><img src="uploads/focus.jpg" alt=""></a></li>
            <li><a href="javascript:"><img src="uploads/focus1.jpg" alt=""></a></li>
            <li><a href="javascript:"><img src="uploads/focus2.jpg" alt=""></a></li>
            <li><a href="javascript:"><img src="uploads/focus3.jpg" alt=""></a></li>
        </ul>
        <ol>
        </ol>
        
        <div class="arrow-l"><a href="javascript:"><</a></div>
        <div class="arrow-r"><a href="javascript:">></a></div>
    </div>
</body>
</html>
3.2 swiper.js
window.addEventListener('load', function () {
    // 轮播图大盒子
    let swiper = document.querySelector('.swiper');
    // 轮播图列表
    let ul = document.querySelector('ul');
    // 底部小圆点列表
    let ol = document.querySelector('ol');
    // 轮播图 "原本" 图片个数
    let imgLen = ul.children.length;
    // 图片宽度
    let imgWidth = ul.children[0].offsetWidth;
    // 左按钮
    let btn_l = document.querySelector('.arrow-l');
    // 右按钮
    let btn_r = document.querySelector('.arrow-r');
    // 当前轮播图的序号
    let num = 0;
    // 小圆点的序号
    let circle = 0;
    // 节流阀
    let flag = true;
    let callback = () => {flag = true};
    // 先把第一个li元素克隆,然后插入到轮播图末尾,方便无缝播放
    let first = ul.children[0].cloneNode(true);
    ul.appendChild(first);
    // 创建imgLen个小圆点,并且对每个小圆点添加一个事件监听器
    // 点击小圆点的时候,先把所有小圆点的类名设置为空,再把当前小圆点的类名设置为‘current’
    // 设置num 和 circle
    // 调用animate函数
    for (let i = 0; i < imgLen; i++) {
        let li = document.createElement('li');
        // li.setAttribute('index', 'i');
        if (i === 0) {
            li.className = 'current';
        }
        ol.appendChild(li);
        ol.children[i].addEventListener('click', function () {
            for (let j = 0; j < imgLen; j++) {
                ol.children[j].className = '';
            }
            ol.children[i].className = 'current';
            num = i;
            circle = i;
            animate(ul, -imgWidth * i);
        })
    }
    // 为了防止连续点击按钮导致轮播图移动太快,设置一个节流阀
    // 当flag为true时,成功触发监听器,然后把flag设置为false,
    // 直到动画完成,再调用callback把flag设置为true
    // 当num == 0时,
    btn_r.addEventListener('click', function () {
        if (flag) {
            flag = false;
            num++;
            // 当播放到最后一张图片(也就是第一张图片时),设置一下轮播图的left
            // 轮播图直接转换到第一张图片,再让num = 1,这样就可以直接跳转到第二张图片
            if (num === imgLen + 1) {
                ul.style.left = 0 + 'px';
                num = 1;
            }
            animate(ul, -num * imgWidth, callback);
            circle++;
            if (circle === imgLen) {
                circle = 0;
            }
            for (let i = 0; i < imgLen; i++) {
                ol.children[i].className = '';
            }
            ol.children[circle].className = 'current';
        }
    });
    btn_l.addEventListener('click', function () {
        if (flag) {
            flag = false;
            num--;
            // 当播放到第一张图片时,让轮播图处于最后一张图片(实际就是第一张图片)
            // 再让num = imgLen - 1,也就是倒数第二张图片的序号
            if (num < 0) {
                ul.style.left = -imgLen * imgWidth + 'px';
                num = imgLen - 1;
            }
            animate(ul, -num * imgWidth, callback);
            circle--;
            if (circle < 0) {
                circle = imgLen - 1;
            }
            for (let i = 0; i < imgLen; i++) {
                ol.children[i].className = '';
            }
            ol.children[circle].className = 'current';
        }
    })
//    自动播放功能
    let autoplay = setInterval(function () {
        btn_r.click();
    }, 2000);
    swiper.addEventListener('mouseenter', function () {
        clearInterval(autoplay);
    })
    swiper.addEventListener('mouseleave', function () {
        autoplay = setInterval(function () {
            btn_r.click();
        }, 2000);
    })
});
3.3 animate.js
function animate(obj, target, callback) {
    clearInterval(obj.timer);
    obj.timer = setInterval(function () {
        let step = (target - obj.offsetLeft) / 10;
        if (obj.offsetLeft === target) {
            clearInterval(obj.timer);
            callback && callback();
        }
        step = step > 0 ? Math.ceil(step) : Math.floor(step);
        obj.style.left = obj.offsetLeft + step + 'px';
    }, 15)
}










