实现比较简单的轮播图效果

实现简单的轮播图效果。

废话不多说,我们开始。

HTML和CSS较为简单,不在这里做赘述。简单的给大家一个HTML代码。

<div class="carousel">
            <div id="goLeft"></div>
            <ul>
                <li><img src="" /></li>
                <li><img src="" /></li>
                <li><img src="" /></li>
                <li><img src="" /></li>
            </ul>
            <div id="goRigth"></div>
        <div class="down"></div>
</div>

以下操作均是根据第一段代码所做的操作。

轮播图要怎们动,首先要明确思路,我们的需求是什么,其实很简单。我们需要是假如我们在点击goRight一次时,ul的依据自身向右偏移1个li的宽度的距离,点击两次时,依据自身偏移两个li宽度距离,以此类推。

但是我们需要思考一个问题,当我们移到第四张,下一次点击我们需要回到第一张,此时,ul向右移动了3个li宽度的距离,假设我们设置在ullefe为3个li宽度时,ulleft值为0,我们可以实现回到第一张,经过实践,会发现第四张图片会一瞬即逝,我们无法停留在第四张图片,这不是我们希望的,我们需要的是第四张图片依旧存在,但是又需要下次点击回到第一张图片。

理所应当我们有一个解决方法,我们先克隆一份第一个li内容,插入到li最后,我们结束第三次点击时,这时我们“身处”第四张图片,第四次点击时,我们会看到“第一张图片(这是我们提前拷贝好插入到最后的那个图片)”,此时我们看到的就是”第一张图片“,之后我们就悄悄的将ulleft值重置到最初的状态,即ul.style.left=0。(需要注意的是:当我们点击goLeft时,我们需要看到我们的倒数第二张图片,所有我们要将第一张图片拷贝添加后的倒数第二张图片也拷贝一次,添加到li最前面,这样我们在点击向左时,利用同样的方法,悄悄的将ulleft值在做修改就好了)。最后我们给ul添加一个过渡动画,这样看起来更加好看。

关于代码的详细思路:

1.先给左右两边的”按钮“添加监听事件,并判断动画是否完成。监听事件的函数我们传入一个 参数,以此判断我们时点击左边的还是右边的。并完成变量声明。

var goLeft = document.getElementById("goLeft"),
                goRight = document.getElementById("goRigth"),
                ul = document.getElementsByTagName("ul")[0],
                li = document.getElementsByTagName("li"),
                carousel = document.getElementsByClassName("carousel")[0],
                liWidth = li[0].offsetWidth,
                liLength = li.length,
                i = 1,    //这里的i是判断ul偏移几个li的宽度的距离。
                btn = true;
        goRight.addEventListener("click", function() {
                if(btn) {
                    go('rigth')
                }
            });

         goLeft.addEventListener("click", function() {
                if(btn) {
                    go('left')
                }
            });
// btn按钮是我们提前定义的 var btn=true;

2.给监听事件的函数添加内容,首先我们需要先根据参数判断是点击左边还是右边的,当判断点击右边时,i++,当判断右边时,i--,同时给btn赋值false,最后给ul设置偏移量,为了良好的用户体验。

(以下两段代码在”function go(frow){}“中)。

         frow == 'rigth' ? i++ : i--;
                btn = false;
                ul.style.transform = 'translateX(-' + i * liWidth + 'px)';
                ul.style.transition = "all .5s ease";

3.判断临界值并执行阻断一次JS。

            ul.addEventListener("transitionend", function() {                    // 本次点击动画完成后,重新赋值btn,并判断是否到达临界图片。
                    btn = true;
                    if(i == liLength + 1) {                                      // 向右点击,到达临界图片,取消ul动画,重新赋值i
                        ul.style.transition = "none";
                        i = 1;
                    }
                    if(i == 0) {                                                 // 向左点击,到达临界图片,取消ul动画,重新赋值i
                        ul.style.transition = "none";
                        i = liLength;
                    }
                    ul.style.transform = 'translateX(-' + i * liWidth + 'px)';   //到达临界图片,悄悄改变ul.style.left
                    getComputedStyle(ul).width;                                  //阻断JS线程 (为什么,我也没懂暂时)
                    ul.style.transition = "all .5s ease";                        //重新给ul添加动画

                })

至此,一个最基本的轮播图就做好了。

以下是完整代码(包含轮播图中小点控制图片)

HTML代码如下

    <div class="carousel">
            <div id="goLeft"></div>
            <ul>
                <li><img src="img/33.jpg" /></li>
                <li><img src="img/22.jpg" /></li>
                <li><img src="img/11.jpg" /></li>
                <li><img src="img/55.jpg" /></li>
            </ul>
            <div id="goRigth"></div>
            <div class="down"></div>
        </div>

CSS代码如下

        div {
                 790px;
                height: 340px;
                position: relative;
                overflow: hidden;
            }
            
            ul {
                 9999px;
                height: 340px;
                font-size: 0;
                position: absolute;
                left: 0;
                list-style: none;
            }
            
            li {
                display: inline-block;
            }
            
            img {
                 100%;
            }
            
            #goLeft,
            #goRigth {
                 50px;
                height: 340px;
                background: rgba(0, 0, 0, 0.5);
                position: absolute;
                z-index: 99;
            }
            
            #goLeft {
                left: 0;
            }
            
            #goRigth {
                right: 0;
            }
            
            .down {
                display: flex;
                position: absolute;
                left: 355px;
                top: 305px;
            }
            
            .dot {
                 20px;
                height: 20px;
                background-image: url(img/icheck_red2.png);
                background-position: 161px 29px;
                margin-right: 3px;
            }
            
            .active {
                background-position: 117px 29px
            }

JS代码如下

        //声明变量
            var goLeft = document.getElementById("goLeft"),
                goRight = document.getElementById("goRigth"),
                ul = document.getElementsByTagName("ul")[0],
                li = document.getElementsByTagName("li"),
                carousel = document.getElementsByClassName("carousel")[0],
                liWidth = li[0].offsetWidth,
                liLength = li.length,
                i = 1,
                btn = true,
                dot = document.getElementsByClassName("dot");

            //代码开始
            ul.style.transform = 'translateX(-' + i * liWidth + 'px)';
            
            //克隆第一张图片插到最后,克隆最后一张图片插到最前面
            var liFirst = li[0].cloneNode(true);
            ul.appendChild(liFirst);
            var liLast = li[liLength - 1].cloneNode(true);
            ul.insertBefore(liLast, li[0]);


            goRight.addEventListener("click", function() {
                if(btn) {
                    go('rigth')
                }
            });

            goLeft.addEventListener("click", function() {
                if(btn) {
                    go('left')
                }
            });

            function go(frow) {
                frow == 'rigth' ? i++ : i--;
                btn = false;
                ul.style.transform = 'translateX(-' + i * liWidth + 'px)';
                ul.style.transition = "all .5s ease";

                ul.addEventListener("transitionend", function() {
                    for(var k = 0; k < liLength; k++) {
                        dot[k].classList.remove("active")
                    }                                               // 这个循环是循环移除激活类
                    btn = true;
                    if(i == liLength + 1) {
                        ul.style.transition = "none";
                        i = 1;
                    }
                    if(i == 0) {
                        ul.style.transition = "none";
                        i = liLength;
                    }
                    dot[i-1].classList.add("active");               //设置当前li添加激活类
                    ul.style.transform = 'translateX(-' + i * liWidth + 'px)';
                    getComputedStyle(ul).width;
                    ul.style.transition = "all .5s ease";

                })
            }

            //创建圆点
       //
var down = document.querySelector(".down");         //循环创建和图片数量相等的小点 for(let i = 0; i < liLength; i++) { down.innerHTML += "<div class='dot'></div>" }
        //外层循环是循环给小点添加点击事件
var circles = document.querySelectorAll(".dot"); for(var m = 0; m < circles.length; m++) { circles[0].classList.add("active"); //给第一个小点最先添加一个激活类 (function(m) { circles[m].addEventListener("click", function() { for(var k = 0; k < circles.length; k++) { //内层循环清除所有小点的激活类 circles[k].classList.remove('active') } this.classList.add("active"); //给当前的小点添加激活类 ul.style.transform = "translateX(-" + (m + 1) * liWidth + "px)"; //点击小点,设置ul偏移量 ul.style.transition = 'all .5s ease'; //ul动画 i = m + 1; // 重点:将点击左右控制轮播图和点击小点控制轮播图联系起来,我们知道i是和第几张图片是一一对应的,i从1开始,m从0开始。既然要联系,那简单来说 }) // 就是用一个关系式把i和m联系起来,即i=m+1 })(m); }
原文地址:https://www.cnblogs.com/Steeland/p/7087941.html