• 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;
                 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;
                 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 {
                 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">&lt;</div>
                <div class="item rightArrow">&gt;</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|)

     
  • 相关阅读:
    Electron dialog 对话框的使用
    Electron BrowserView 的使用
    自动化测试相关
    使用chrome开发者工具中的performance面板解决性能瓶颈
    Electron window.open 函数 和 Browser-window-proxy 对象的使用
    Electron webview 标签
    Electron File对象
    Electron 进程
    JAVA日报
    JAVA日报
  • 原文地址:https://www.cnblogs.com/lanshanxiao/p/12813391.html
Copyright © 2020-2023  润新知