21.JavaScript实现无缝轮播图

JavaScript实现无缝轮播图:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .container {
            position: relative;
            width: 500px;
            height: 400px;
            border: 1px solid #fff;
            margin: 20px auto;
            overflow: hidden;
            cursor: pointer;
        }

        .container .images img {
            display: block;
            float: left;
        }

        .container .dots {
            position: absolute;
            margin: 0 auto;
            left: 0;
            right: 0;
            bottom: 10px;
            background: rgba(255, 255, 255, .3);
            padding: 5px;
            border-radius: 20px;
        }

        .container .dots span {
            margin: 2px;
            width: 8px;
            height: 8px;
            display: block;
            border-radius: 50%;
            background: rgba(255, 255, 255, .5);
            float: left;
        }

        .container .dots span.active {
            background: #f40;
        }

        .container .arrow {
            display: none;
        }

        .container:hover .arrow {
            display: block;
        }

        .container .arrow .item {
            width: 40px;
            height: 40px;
            background: rgba(255, 255, 255, .5);
            color: #fff;
            position: absolute;
            top: 0;
            bottom: 0;
            margin: auto 0;
            text-align: center;
            line-height: 40px;
            font-size: 20px;
        }

        .container .arrow .leftArrow {
            left: 0;
            border-radius: 0 20px 20px 0;
        }

        .container .arrow .rightArrow {
            right: 0;
            border-radius: 20px 0 0 20px;
        }
    </style>
</head>

<body>
    <div class="container">
        <div class="images">
        </div>
        <div class="dots">
        </div>
        <div class="arrow">
            <div class="item leftArrow"><</div>
            <div class="item rightArrow">></div>
        </div>
    </div>
    <script>
        var config = {
            imgWidth: 500, //图片宽度
            dotWidth: 12, //小圆点宽度
            imageArray: ["./image/5.jpg", "./image/1.jpg", "./image/2.jpg", "./image/3.jpg", "./image/4.jpg",
                "./image/5.jpg", "./image/1.jpg"
            ], //存储图片路径的数组
            doms: {
                images: document.querySelector(".images"), //存放图片的dom
                dots: document.querySelector(".dots"), //圆点的dom
                leftArrow: document.querySelector(".item.leftArrow"), //左一张的dom
                rightArrow: document.querySelector(".item.rightArrow") //右一张的dom
            },
            currentIndex: 2, //当前展示的图片下标
            timer: { //计时器配置
                id: null, //计时器id
                duration: 16, //每次切换图片,运动的间隔时间
                totalTime: 1000 //每次切换图片,运动的时间总长
            }
        };
        initImages();
        initDots();

        //初始化图片元素
        function initImages() {
            //创建图片元素
            config.doms.images.style.width = config.imageArray.length * config.imgWidth + "px";
            for (var i = 0; i < config.imageArray.length; i++) {
                var img = document.createElement("img");
                img.src = config.imageArray[i];
                config.doms.images.appendChild(img);
            }

            //展示第一张图片1.jpg
            config.doms.images.style.marginLeft = -config.imgWidth * config.currentIndex + "px";
        }

        //创建圆点元素
        function initDots() {
            config.doms.dots.style.width = (config.imageArray.length - 2) * config.dotWidth + "px";
            for (var i = 0; i < config.imageArray.length - 2; i++) {
                var dot = document.createElement("span");
                config.doms.dots.appendChild(dot);
            }

            config.doms.dots.children[config.currentIndex - 1].className = "active";
        }

        //点击左箭头、右箭头、和圆点
        config.doms.leftArrow.onclick = config.doms.rightArrow.onclick = config.doms.dots.onclick = function (e) {
            if (e.target.tagName === "DIV" && e.target.classList.contains("leftArrow")) { //点击左箭头
                var index = config.currentIndex - 1;//向左跳转图片的下标
                if(index === 0){//
                    index = 5;
                }
                jumpToImage(index, "left");
            } else if (e.target.tagName === "DIV" && e.target.classList.contains("rightArrow")) { //点击右箭头
                var index = config.currentIndex + 1;//向右跳转图片的下标
                if(index === 6){//
                    index = 1;
                }
                jumpToImage(index, "right");
            } else if (e.target.tagName === "SPAN" && e.target.parentElement && e.target.parentElement.classList
                .contains("dots")) { //点击小圆点
                var index = Array.from(config.doms.dots.children).indexOf(e.target) + 1;
                jumpToImage(index, (index > config.currentIndex) ? "right" : "left");
            }
        }

        //跳转到哪张图片
        function jumpToImage(index, direction) { //index:下一张图片的下标(1,25);direction方向(1.left:左;2.right:右);
            if (index === config.currentIndex) { //若要跳转的图片下标和当前下标一样,不执行
                return;
            }
            if (!direction) { //方向默认:为右
                direction = "right";
            }

            //要运动到的目标marginLeft
            var newMarginLeft = -index * config.imgWidth;
            //图片切换
            //config.doms.images.style.marginLeft = newMarginLeft + "px";
            autoPlay();
            //圆点也自动切换
            for (var i = 0; i < config.doms.dots.children.length; i++) {
                config.doms.dots.children[i].classList.remove("active");
            }
            config.doms.dots.children[index - 1].className = "active";
            //切换完成后,改变当前图片下标
            config.currentIndex = index;

            //图片渐变动画,一点一点的改变marginLeft
            function autoPlay() {
                stopPlay(); //在播放轮播图之前,把上次的动画先停掉

                //当前的marginLeft
                var currentMarginLeft = parseFloat(window.getComputedStyle(config.doms.images).marginLeft);
                //图片总长度,不能算第一张和最后一张,这两张是额外增加重复的两张
                var allImagesLength = (config.imageArray.length - 2) * config.imgWidth;
                //1.计算运动总次数
                var frequency = Math.ceil(config.timer.totalTime / config.timer.duration);
                var currentNum = 0; //当前运动的次数
                //2.计算运动的总距离
                var allDistance = 0;
                if (direction == "left") { //向左运动
                    if (newMarginLeft > currentMarginLeft) { //目标marginLeft > 当前marginLeft
                        //总距离 = 目标marginLeft - 当前marginLeft
                        allDistance = newMarginLeft - currentMarginLeft;
                    } else {
                        //总距离 = 图片总长度 - |目标marginLeft - 当前marginLeft|
                        allDistance = allImagesLength - Math.abs(newMarginLeft - currentMarginLeft);
                    }
                } else { //向右运动
                    if (newMarginLeft < currentMarginLeft) { //目标marginLeft < 当前marginLeft
                        //总距离 = 目标marginLeft - 当前marginLeft
                        allDistance = newMarginLeft - currentMarginLeft;
                    } else { //目标marginLeft > 当前marginLeft
                        //总距离 = -(图片总长度 - |目标marginLeft - 当前marginLeft|)
                        allDistance = -(allImagesLength - Math.abs(newMarginLeft - currentMarginLeft));
                    }
                }
                //3.计算每次运动改变的距离
                var everyDistance = allDistance / frequency; //每次运动距离 = 运动总距离 / 运动总次数
                config.timer.id = setInterval(function () {

                    //改变图片的marginLeft
                    currentMarginLeft += everyDistance;
                    //若图片向右移动到额外的第一张(即数组中最后一张图片)
                    if (direction === "right" && Math.floor(Math.abs(currentMarginLeft)) > allImagesLength) {

                        currentMarginLeft += allImagesLength; //图片瞬间挪回第一张图片对应的位置
                    } else if (direction === "left" && Math.ceil(Math.abs(currentMarginLeft)) < config
                        .imgWidth) { //若图片向左移动到额外的最后一张(即数组中第一张图片)
                        currentMarginLeft -= allImagesLength; //图片瞬间挪回最后一张图片对应的位置
                    }
                    config.doms.images.style.marginLeft = currentMarginLeft + "px";
                    currentNum++; //每执行一次,当前运动次数++
                    if (currentNum === frequency) { //达到运动总次数,停止运动
                        stopPlay();
                    }
                }, config.timer.duration);
            }
            //停止播放
            function stopPlay() {
                clearInterval(config.timer.id);
                config.timer.id = null;
            }
        }
    </script>
</body>

</html>

index.html

效果展示:

最后一张图片切换第一张图片的效果

图片数组存储一共七张图片,但是1.jpg 和 5.jpg存放了两次,用来衔接。这样从5.jpg切换到1.jpg的时候不会出现断档,五张图片的宽高是500 X 200

制作无缝轮播图的难点:

计算运动的总距离

向左运动,目标margin-left 和 当前的margin-left

目标marginLeft > 当前marginLeft  //总距离 = 目标marginLeft - 当前marginLeft

目标marginLeft < 当前marginLeft  //总距离 = 图片总长度 - |目标marginLeft - 当前marginLeft|

向右运动,目标margin-left 和 当前的margin-left

目标marginLeft < 当前marginLeft  //总距离 = 目标marginLeft - 当前marginLeft

目标marginLeft > 当前marginLeft  //总距离 = -(图片总长度 - |目标marginLeft - 当前marginLeft|)

 
(0)

相关推荐

  • JavaScript 移动端轮播图

    代码实现: mobileAutoPlay.html(复制并保存为html文件,打开并切换为移动端显示,即可见效果): <!DOCTYPE html> <html lang=" ...

  • JavaScript轮播图

    要求: 鼠标经过轮播图模块,左右按钮显示,离开隐藏左右按钮 点击右侧按钮一次,图片往左播放一张,以此类推,左侧按钮同理 图片播放的同时,下面小圆圈模块跟随一起变化 点击小圆圈,可以播放相应图片 鼠标不 ...

  • android 轮播图

    不点蓝字,我们哪来故事? 国庆节前,教大家一步步搞回了两步路(户外助手)的 谷歌卫星图 和 路网. 错过的朋友可以看之前的文章:快速找回 两步路(户外助手) 的谷歌卫星图&路网 但是文章发出后 ...

  • 通过Swiper网站使用轮播图的切换效果

    这里写目录标题 通过Swiper网站使用轮播图的切换效果 1.通过网络地址引入或者下载到本地 2.写入html结构 3.设置复盒子宽高 4.写入轮播图切换效果的方法 通过Swiper网站使用轮播图的切 ...

  • PPT展示多图怎么办?试试轮播图效果

    @三水 hello,大家好,这里是珞珈老师,我是三水. 要展示多张图片的时候,很多同学不知道该怎么处理,觉得无论怎么排都不好看. 这个时候你可以尝试做一个轮播图效果,可以帮助你解决多图展示排版难题. ...

  • 两种轮播图实现方式

    最近做了一个网站,首页轮播图一直没有达到理想的效果,在网上找了两个实现方法,一个是用css自己实现,一个是用swiper插件,个人认为swiper做的还比较好用.这里只贴出主要的实现代码,想要看具体实 ...

  • js实现无缝连接轮播图(四)点击小圆点,移动图片

    <!-- 这个animate.js 必须写到 index.js的上面引入 --> <script src="js/animate.js"></scri ...

  • js实现无缝连接轮播图(三)使用排他思想,实现小圆点填充颜色的切换

    <!-- 这个animate.js 必须写到 index.js的上面引入 --> <script src="js/animate.js"></scri ...

  • WEB前端第四十五课——jQuery框架(三)animate、轮播图&百叶窗案例

    WEB前端第四十五课——jQuery框架(三)animate、轮播图&amp;百叶窗案例