原生JS实现无缝轮播效果

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>原生JS无缝轮播图</title>
    <script type="text/javascript" src="../bootstrap-3.3.7/js/jquery2.0.js"></script>
    <style>
        * {
            font-family: 微软雅黑;
        }

        .container {
            width: 1140px;
            padding: 0 15px;
            margin: 0 auto;
        }

        #zz_carousel {
            width: 1140px;
            height: 500px;
            overflow: hidden;
            position: relative;
        }

        #zz_carousel:hover .arrow {
            display: block;
        }

        #zz_carousel .paging {
            position: absolute;
            bottom: 15px;
            left: 50%;
            /*display: none;*/
        }

        #zz_carousel .paging span {
            display: inline-block;
            width: 15px;
            height: 15px;
            border-radius: 50%;
            background-color: #eee;
            margin-left: 15px;
            cursor: pointer;
        }

        #zz_carousel .paging span.active {
            background-color: darkslategrey;
        }

        #zz_carousel .image_reel {
            position: absolute;
        }

        #zz_carousel .image_reel img {
            width: 1140px;
            height: 500px;
            float: left;
        }

        #zz_carousel .next {
            position: absolute;
            top: 50%;
            margin-top: -50px;
            right: 0;
        }

        #zz_carousel .previous {
            position: absolute;
            top: 50%;
            margin-top: -50px;
            left: 0;
        }

        a {
            text-decoration: none;
            color: #fff;
        }

        #zz_carousel .arrow {
            font-size: 50px;
            display: none;
        }

        #zz_carousel .arrow:hover {
            background-color: #f0f3ef;
            color: #091b22;
        }
    </style>
</head>
<body>

<!--
 一. 使用:
 1. 修改 .container 的width
        .carousel  的width height
        #zz_carousel .image_reel img 的width height
        即可修改图片的大小,当时以上属性要一致
 2. 在image_reel中添加相同代码即可插入图片

 3. 在JS中修改自动播放中定时器的延时即可修改自动播放的速度

二. 代码关键点:

    1.var imgs = image_reel.children; 这里的imgs会随着文档的变化来更新

    2. var picIdx = 0;  把这个属性设置为全局变量,保存当前图片的索引,也用来关联小圆点切换和左右按钮切换的逻辑
-->


<div class="container">
    <div class="carousel" id="zz_carousel">
        <!--图片容器,移动的元素-->
        <div class="image_reel">
            <a href="#"><img src="images/1.jpg" alt=""></a>
            <a href="#"><img src="images/2.jpg" alt=""></a>
            <a href="#"><img src="images/3.jpg" alt=""></a>
            <a href="#"><img src="images/4.jpg" alt=""></a>
            <a href="#"><img src="images/5.jpg" alt=""></a>
        </div>
        <!--图片下方的小圆点,js动态添加-->
        <div class="paging"></div>
        <!--左右控制按钮-->
        <div class="change">
            <sapn class="previous"><a href="#" class="arrow">&lt;</a></sapn>
            <span class="next"><a href="#" class="arrow">&gt;</a></span>
        </div>
    </div>
</div>
<script>
    window.addEventListener('load', function () {
        //变速平移动画函数
        function animate(ele, target) {
            clearInterval(ele.timer);
            ele.timer = setInterval(function () {
                var current = ele.offsetLeft;
                var step = (target - current) / 6;
                step = step > 0 ? Math.ceil(step) : Math.floor(step);
                current += step;
                ele.style.left = current + 'px';
                if (current == target) {
                    clearInterval(ele.timer);
                }
            }, 30);
        }

        // 获取元素
        var carousel = document.getElementById('zz_carousel');
        var image_reel = carousel.children[0];
        var paging = carousel.children[1];
        var change = carousel.children[2];
        var imgs = image_reel.children;
        var imgWidth = carousel.offsetWidth;

        // ************************注意************************
        //console.log(imgs);//HTMLCollection(3)
        // 1. 在将第一个图片复制到文档之前,imgs的长度为代码中图片的个数,但是imgs为HTMLCollection
        // 该属性会随着文档的变化动态更新,所以添加图片后imgs的length为4

        //1. 点击小圆点切换图片
        var picIdx = 0;
        // 根据图片的个数在页面中加入小圆点
        for (var i = 0; i < imgs.length; i++) {
            var span = document.createElement('span');
            //为每个span添加索引值
            span.index = i;
            paging.appendChild(span);
            // 给每个小圆点添加点击 事件
            span.addEventListener('click', function () {
                //切换active
                for (var i = 0; i < paging.children.length; i++) {
                    paging.children[i].className = '';
                }
                this.className = 'active';
                //获取点击span的索引值
                picIdx = this.index;
                //移动image_reel
                animate(image_reel, -picIdx * imgWidth);
            });
        }
        //默认第一个为选中
        paging.children[0].className = 'active';
        //给paging设置margin-left 让它居中
        paging.style.marginLeft = -paging.offsetWidth / 2 + 'px';


        // 2. 将第一张图片复制一份放在最后,方便实现无缝滚动
        var tempImg = imgs[0].cloneNode(true);
        image_reel.appendChild(tempImg);
        // 给 image_reel 加宽,宽度为img的个数加img宽度
        image_reel.style.width = imgWidth * imgs.length + 'px';

        // 3. 左右控制按钮
        var previous = change.children[0];
        var next = change.children[1];
        //上一张
        previous.addEventListener('click', function () {
            if (picIdx == 0) {
                picIdx = imgs.length - 1;
                image_reel.style.left = -(imgs.length - 1) * imgWidth + 'px';
            }
            picIdx--;
            animate(image_reel, -picIdx * imgWidth)
            // 同步小圆点的显示
            for (var i = 0; i < paging.children.length; i++) {
                paging.children[i].className = '';
            }
            paging.children[picIdx].className = 'active';

        });
        // 下一张
        next.addEventListener('click', turnNext);

        function turnNext() {
            //当现实最后一张图片时(与第一张相同),马上跳转回开始的位置,并向下一张移动
            if (picIdx == imgs.length - 1) {//这里的length在图片加入后计算的,数值为代码中的图片个数+1
                picIdx = 0;
                image_reel.style.left = 0 + 'px';
            }
            picIdx++;
            animate(image_reel, -picIdx * imgWidth)
            // 同步小圆点的显示
            if (picIdx == imgs.length - 1) {//当图片是最后一张是,应当认为是第一张,做特殊处理
                paging.children[paging.children.length - 1].className = '';
                paging.children[0].className = 'active';
            } else {
                //切换active
                for (var i = 0; i < paging.children.length; i++) {
                    paging.children[i].className = '';
                }
                paging.children[picIdx].className = 'active';
            }
        }

        //3. 自动播放 即自动调用下一张的点击函数即可
        var timer = setInterval(function () {
            turnNext();
        }, 3000);

        //4. 鼠标放入图片停止滚动
        carousel.addEventListener('mouseenter', function () {
            clearInterval(timer);
        });
        carousel.addEventListener('mouseleave', function () {
            timer = setInterval(function () {
                turnNext();
            }, 3000);
        });

    });

</script>
</body>
</html>

如果有发现bug和改进的地方,欢迎提出意见,感谢

猜你喜欢

转载自blog.csdn.net/hgzzzz/article/details/81501598