原生js手撕无缝轮播图

1,874 阅读1分钟

效果图

滚动原理

给父类添加transform的过渡动画,利用js计算图片宽度,然后对父类的translateX属性进行修改,即可实现图片滚动。

无缝原理

在图标列表的尾部加入第一个图,在头部加入最后一个如.

即 原: [1, 2, 3, 4]; 修改后:[4, 1, 2, 3, 4, 1]

然后在过渡到修过后的最后一个元素时(即上方[4, 1, 2, 3, 4, 1]里的最后一个1), 进行如下步骤:

1、利用js删除动画效果

2、重置过度位置

3、强制出发浏览器重绘(因为下一步需要恢复css动画,浏览器的重绘是在下一个tick进行的。如果不在此时强制出发浏览器重绘,在浏览器进行重绘时,下方恢复css动画的语句已经被执行,所以就还是会有动画效果。)

4、恢复动画效果

代码展示

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <style type="text/css">
        body {
            margin: 0;
        }
        .slider {
            margin: 0 10%;
            overflow: hidden;
        }
        .imgs {
            display: flex;
            flex-wrap: nowrap;
            height: 200px;
            width: 100%;
        }
        .img {
            flex: 0 0 auto;
            height: 100%;
            width: 100%;
        }
        .img.img-1 {
            background: red
        }
        .img.img-2 {
            background: blue
        }
        .img.img-3 {
            background: gray
        }
        .img.img-4 {
            background: green
        }
        .img.img-5 {
            background: black
        }

    </style>
</head>
<body>
    <div class="slider">
        <div class="imgs">
            <div class="img img-5"></div>
            <div class="img img-1"></div>
            <div class="img img-2"></div>
            <div class="img img-3"></div>
            <div class="img img-4"></div>
            <div class="img img-5"></div>
            <div class="img img-1"></div>
        </div>
    </div>
</body>
<script type="text/javascript">
    const dom = document.querySelector('.imgs')
    slider(dom)
    function slider (el) {
        const width = el.children[0].offsetWidth
        const length = getChildren(el).length
        el.style.transform = `translateX(-${width}px)`
        el.offsetHeight
        startSlide(el, width, length)
    }

    function startSlide (el, width, length) {
        let i = 2
        el.style.transition = 'all 1s'
        el.addEventListener('transitionend', () => {
            i++
            // 重置图片位置
            if (i >= length) {
                el.style.transition = ''
                i = 2
                el.style.transform = `translateX(-${width}px)`
                el.offsetHeight
                el.style.transition = 'all 1s'
            } 
            setTimeout(() => {
                el.style.transform = `translateX(-${width * i}px)`
            }, 1000)
            
        })
        setTimeout(() => {
            el.style.transform = `translateX(-${width * i}px)`
        }, 1000)
    }

    function getChildren (el) {
        return [...el.children]
    }
</script>
</html>