【学会轮播图这一篇文章就足够啦】JS 网页轮播图详解 自动播放+手动播放

发布时间:2023-08-16 11:30

轮播图已经成了页面开发中不可缺少的一部分,日常生活中随处都能见到轮播图的身影,例如平常我们购物的淘宝,京东等等,都靠着轮播图在一片 有限的区域内展现出更多的商品。这也是前端程序员最早接触到的练手小项目,这篇文章带大家透彻拿下轮播图!从此不再迷茫

 首先我们来看一下本次案例的效果:

(下面有请本人女朋友出境!话说我是在搞不明白 gif 图怎么设置,但总之就是该有的功能都有,不该有的功能也有(例如杀狗 hhhhh),自动播放,点击切换按钮切换图片,点击下方圆点切换图片均可实现,就不一一演示了,主要还是让大家搞明白原理是什么)

\"\"

我将拆分成下面几个步骤依次讲解

  1. 轮播图的基本结构搭建及原理分析
  2. 光标移动至轮播图处切换按钮的显示与隐藏
  3. 点击下方按钮切换图片的实现
  4. 右侧按钮滚动实现 以及 下方点点同步改变
  5. 左侧按钮滚动实现 以及 下方点点同步改变
  6. 自动播放实现

一: 轮播图的基本结构搭建及原理分析

其实轮播图的构成很简单,仅由显示区域和图片区域两部分组成,图片区域由一个 ul 标签实现,内部一个 li 标签里放一张图片,使其左浮动形成一行,其移动其实靠的就是 ul 的 动画原理 左右移动来改变显示区域,效果如下:(页面结构的HTML与CSS,还有封装好的动画函数js文件在文章末尾)

\"\"


二: 光标移动至轮播图处切换按钮的显示与隐藏

 光标移动到轮播图区域使左右切换图片按钮显示与隐藏,我们用到两个事件分为: mouseenter 和 mouseleave,之所以不用 mouseover 和 mouseout 是因为这两个事件会冒泡,会产生很多不可控的影响,但两组事件的效果几乎完全相同。绑定事件后改变按钮的 display 值即可。

首先我们先了解一下获取到的元素有哪些,以免下面的分步讲解有疑惑的地方:

    var leftbtn=document.querySelector('.leftbtn');   //左按钮
    var rightbtn=document.querySelector('.rightbtn');  //右按钮
    var windows=document.querySelector('.windows');  //显示窗口区域
    var circleul=document.querySelector('.imgbox');  //装图片的 ul
    var circleol=document.querySelector('.circle');  //装下方小点点的 ol

此部分是 光标移动至轮播图处切换按钮的显示与隐藏 的实现:

  windows.addEventListener('mouseenter',function(){
        leftbtn.style.display='block';
        rightbtn.style.display='block';
        clearInterval(timer)    //清除定时器自动播放,此处不需要管
        timer=null;
    })
    windows.addEventListener('mouseleave',function(){
        leftbtn.style.display='none'
        rightbtn.style.display='none'
        timer=setInterval(function(){
            rightbtn.click();
        },2000)
    })
    leftbtn.addEventListener('click',function(){  //按钮点击后变色一下的效果
        leftbtn.style.color='grey'
        var timer=setTimeout(function(){
            leftbtn.style.color='aliceblue'
        },100)
    })
    rightbtn.addEventListener('click',function(){
        rightbtn.style.color='grey'
        var timer=setTimeout(function(){
           rightbtn.style.color='aliceblue'
        },100)
    })

 三:点击下方按钮切换图片的实现

for循环的作用为根据 ul 中图片的个数来添加 ol 中小点点的个数并添加在 ol 中,给创建的 li 添加自定义属性 indexfor 循环的 i 作为其每个 li 的属性值,而图片作为ul的子节点,分别对应 children[0],children[1],children[2],children[3],正好与自定义属性的 index 一一对应,也就是说每个点点都配对一个同样序号的图片。

在添加每个 li 的同时就给每个 li 绑定点击事件,并获取该自定义属性index,使用 排他思想 更改点击的原点的颜色,并调用封装好的动画函数就可以完成点击小圆点切换图片的效果

\"\"

 这两行是移动的关键代码:windows.offsetWidt 作用是获取每张图片的宽度,-6 是为了消除一些移动中由于图片与图片之间间隔产生的误差

var imgwidth=windows.offsetWidth-6;
var long=this.getAttribute('index')*imgwidth;

点第一个小点点:

\"\"

 点第二个小点点:

\"\"

 点第三个小点点:

\"\"

代码实现:

 for(var i=0;i<circleul.children.length;i++){   //根据图片个数自动创建小点点个数
        lis=document.createElement('li');
        lis.setAttribute('index',i);
        circleol.appendChild(lis);
        lis.addEventListener('click',function(){
            var currentindex=this.getAttribute('index'); //bug整改
            num=currentindex;  //bug整改
            circlechange=currentindex;  //bug整改
            for(var i=0;i<circleol.children.length;i++){  //排他思想
                circleol.children[i].className='';
            }
            this.className='circlecolor';
            var imgwidth=windows.offsetWidth-6;
            var long=this.getAttribute('index')*imgwidth;
            run(circleul,-long);  //封装好的动画函数
        })
    }

 四:右侧按钮滚动实现 以及 下方点点同步改变

总算到了关键的一步,通过按钮来使轮播图运动,也是本案例最抽象的一部分,抽象在它最后一张和第一张的无缝衔接,此处要说明我们要使其无缝衔接的原理,是将第一张图片克隆一份放在最后一张图片的后面(下方点点数不包括克隆的这一张图片,但是ul 的子元素包含了这个新克隆的图片!),在图片滚动到该克隆图片后,立马将其 ul 的 left 值改为 0 。

克隆第一张图片我们使用节点的带参克隆 :

var firstimg=circleul.children[0].cloneNode(true);
circleul.appendChild(firstimg);

我们已经知道了图片滚动的距离等于该图片的顺序乘图片宽度,在这里我们先设置一个全局变量num,并设初始值为0,点击一次右侧按钮则 num 自增1,第一次点击 num自增1, num=1,移动距离为 1✖宽度,第二次点击 num 自增 1,num=2,移动距离为 2✖宽度,前面几步都好理解,但是当num 为最后无缝衔接时需要一个判断语句,我们重点研究无缝衔接的原理: 

第一次点击右侧按钮后: 

\"\"

 第二次点击右侧按钮后:

\"\"

 第三次点击右侧按钮后:

\"\"

第四次点击右侧按钮后:

注意此步骤判断前 num=3,即不执行判断里的语句,但是判断完后num自增为4,也就是说下一次就要执行判断里的语句

\"\"

 第五次点击右侧按钮后:

为什么点击后直接到了第二张图片呢?不是在判断语句里设置了left为0吗?这是因为判断中设置了num=0和left=0后才自增1,所以这一次点击后带入动画函数的num=1,移动距离为1✖宽度,又开始新一轮循环图片!

\"\"

代码实现:

    num=0;
    circlechange=0;  //目的为下方点点同步改变时使用,这一步先不用管这个参数
    rightbtn.addEventListener('click',function(){
        if(num==circleul.children.length-1){
            circleul.style.left=0;
            num=0;
        }
        num++;
        long=num*windows.offsetWidth-6*num;
        run(circleul,-long);

我们点击右侧按钮,图片滚动的同时,小圆圈也应该跟着切换才对,该怎么实现呢?

每点击一次都让circlechange这个变量自增,当自增到值和 circleul.children.length-1 的值相等时(即滚动到了克隆过去的最后一张图片),这时让 circlechange 变为 0 即可

  circlechange++;
        if(circlechange==circleul.children.length-1){
           circlechange=0;
        }
        for(var i=0;i<circleol.children.length;i++){  //排他思想
             circleol.children[i].className='';
        }
        circleol.children[circlechange].className='circlecolor';
    })

五:左侧按钮滚动实现 以及 下方点点同步改变 

向左切换和向右切换的原理类似,在此我们只研究第一张图片开始往左无缝衔接最后一张图片的过程

第一次点击左侧按钮后:

\"\"

代码实现: 

 leftbtn.addEventListener('click',function(){
        if(num==0){
            circleul.style.left=(circleul.children.length-1)*windows.offsetWidth;
            num=circleul.children.length-1;
        }
        num--;
        long=num*windows.offsetWidth-6*num;
        run(circleul,-long);

 点击左侧按钮,小圆圈跟随切换:

 circlechange--;
        if(circlechange<0){
           circlechange=circleol.children.length-1;  //注意此处是ol的子节点的长度-1
        }
        for(var i=0;i<circleol.children.length;i++){
             circleol.children[i].className='';
        }
        circleol.children[circlechange].className='circlecolor';
    })

六:自动播放实现

自动播放最简单!,只需要一个自动点击即可

此处为右侧按钮自动点击:rightbtn.click()

将其添加在定时器中就可以完成我们的轮播图啦

 var timer=setInterval(function(){
            rightbtn.click();
        },2000)

完整JS代码:

我们的 JS 是单独的一个文件,所以加入了 load 事件等文档流执行完毕后,再执行 JS 的内容

window.addEventListener('load',function(){
    var leftbtn=document.querySelector('.leftbtn');
    var rightbtn=document.querySelector('.rightbtn');
    var windows=document.querySelector('.windows');
    var circleul=document.querySelector('.imgbox');
    var circleol=document.querySelector('.circle');
    //光标移动至轮播图区域按钮显示,移开隐藏,点击按钮的变化效果
    windows.addEventListener('mouseenter',function(){
        leftbtn.style.display='block';
        rightbtn.style.display='block';
        clearInterval(timer)//清除定时器自动播放
        timer=null;
    })
    windows.addEventListener('mouseleave',function(){
        leftbtn.style.display='none'
        rightbtn.style.display='none'
        timer=setInterval(function(){
            rightbtn.click();
        },2000)
    })
    leftbtn.addEventListener('click',function(){
        leftbtn.style.color='grey'
        var timer=setTimeout(function(){
            leftbtn.style.color='aliceblue'
        },100)
    })
    rightbtn.addEventListener('click',function(){
        rightbtn.style.color='grey'
        var timer=setTimeout(function(){
           rightbtn.style.color='aliceblue'
        },100)
    })
    //点击小圆圈可以滚动
    for(var i=0;i<circleul.children.length;i++){
        lis=document.createElement('li');
        lis.setAttribute('index',i);
        circleol.appendChild(lis);
        lis.addEventListener('click',function(){
            var currentindex=this.getAttribute('index');//bug整改(3行)
            num=currentindex;
            circlechange=currentindex;
            for(var i=0;i<circleol.children.length;i++){
                circleol.children[i].className='';
            }
            this.className='circlecolor';
            var imgwidth=windows.offsetWidth-6;
            var long=this.getAttribute('index')*imgwidth;
            run(circleul,-long);
        })
    }
    circleol.children[0].className='circlecolor';
    //克隆第一张图片至末尾
    var firstimg=circleul.children[0].cloneNode(true);
    circleul.appendChild(firstimg);

//右侧按钮点击滚动
    num=0;
    circlechange=0;
    rightbtn.addEventListener('click',function(){
        if(num==circleul.children.length-1){
            circleul.style.left=0;
            num=0;
        }
        num++;
        long=num*windows.offsetWidth-6*num;
        run(circleul,-long);
    //小圆圈跟着一起变化
        circlechange++;
        if(circlechange==circleul.children.length-1){
           circlechange=0;
        }
        for(var i=0;i<circleol.children.length;i++){
             circleol.children[i].className='';
        }
        circleol.children[circlechange].className='circlecolor';
    })
    //左侧按钮滚动
    leftbtn.addEventListener('click',function(){
        if(num==0){
            circleul.style.left=(circleul.children.length-1)*windows.offsetWidth;
            num=circleul.children.length-1;
        }
        num--;
        long=num*windows.offsetWidth-6*num;
        run(circleul,-long);
    //小圆圈跟着一起变化
        circlechange--;
        if(circlechange<0){
           circlechange=circleol.children.length-1;  //注意此处是ol的子节点的长度-1
        }
        for(var i=0;i<circleol.children.length;i++){
             circleol.children[i].className='';
        }
        circleol.children[circlechange].className='circlecolor';
    })
   //自动播放
        var timer=setInterval(function(){
            rightbtn.click();
        },2000)

})

动画函数代码:


    function run(obj,long,callback){
        clearInterval(obj.timer)
        obj.timer=setInterval(function(){
            if(obj.offsetLeft==long){
                window.clearInterval(obj.timer);
                if(callback){
                    callback();
                }
            }else{
                step=(long-obj.offsetLeft)/10
                step=step>0?Math.ceil(step):Math.floor(step)
                obj.style.left=obj.offsetLeft+step+'px';
            }
        },20)
    }

 

HTML+CSS 完整代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .windows{
            position: relative;
            border: 3px rgb(146, 146, 146) solid;
            width: 700px;
            height: 450px;
            background-color: rgb(250, 186, 186);
            margin: 170px auto;
            overflow: hidden;
        }
        .leftbtn{
            z-index: 999;
             position: absolute;
             box-sizing: border-box;
             top: 195px;
             left: 0;
             width: 50px;
             height: 70px;
             background-color: rgba(136, 135, 135, 0.582);
             line-height: 70px;
             text-align: center;
             font-size: 35px;
             color: rgba(255, 255, 255, 0.609);
             cursor: pointer;
             display: none;
        }
        .leftbtn:hover{
            background-color: rgba(189, 186, 186, 0.623);
            color: aliceblue;
        }
        .rightbtn{
            z-index: 999;
             position: absolute;
             box-sizing: border-box;
             top: 195px;
             right: 0;
             width: 50px;
             height: 70px;
             background-color: rgba(136, 135, 135, 0.609);
             line-height: 70px;
             text-align: center;
             font-size: 35px;
             color: rgba(255, 255, 255, 0.596);
             cursor: pointer;
             display: none;
        }
        .rightbtn:hover{
            background-color: rgba(189, 186, 186, 0.623);
            color: aliceblue;
        }
        .imgbox{
           position:absolute;
           left: 0;
           top: 0;
            box-sizing: border-box;
            width: 700%;
            height: 450px;
        }
        .imgbox li{
            float: left;
            box-sizing: border-box;
            width: 700px;
            height: 450px;
            list-style: none;
        }
        .imgbox li a{
            box-sizing: border-box;
            display: inline-block;
            width: 700px;
            height: 450px;
            background-color: rgb(134, 152, 255);
        }
        .imgbox li a img{
            cursor:auto;
            width: 700px;
            height: 450px;
        }
        .circlebox{
            position: absolute;
            bottom: 0;
            width: 700px;
            height: 40px;
            background-color: rgba(94, 94, 94, 0.486);

        }
        .circle {
            position: absolute;
            bottom: 10px;
            left: 300px;
        }
        .circle li {
            float: left;
            width: 7px;
            height: 7px;
            list-style: none;
            border: 2px solid rgb(185, 185, 185);
            border-radius:100%;
            margin: 3px;
            cursor: pointer;
            background-color: rgb(173, 173, 173);
        }
        .circlecolor{
            background-color: coral !important;
            border: 2px solid coral !important;
        }
    </style>
    <script src="../js/run.js"></script>
    <script src="../js/btn-display.js"></script>
</head>
<body>
    <div class="windows">
        <div class="leftbtn"> < </div>
        <div class="rightbtn"> > </div>
        <ul class="imgbox">
            <li>
                <a href="#"><img src="../轮播photo/1.jpg" alt="轮播图" class="lunboimg"></a>
            </li>
            <li>
                <a href="#"><img src="../轮播photo/2.jpg" alt="轮播图" class="lunboimg"></a>
            </li>
            <li>
                <a href="#"><img src="../轮播photo/3.jpg" alt="轮播图" class="lunboimg"></a>
            </li>
            <li>
                <a href="#"><img src="../轮播photo/4.jpg" alt="轮播图" class="lunboimg"></a>
            </li>
            <li>
                <a href="#"><img src="../轮播photo/5.jpg" alt="轮播图" class="lunboimg"></a>
            </li>
            <li>
                <a href="#"><img src="../轮播photo/6.jpg" alt="轮播图" class="lunboimg"></a>
            </li>
        </ul>
        <div class="circlebox">
               <ol class="circle"></ol>
        </div>
      
     
       
    </div>
</body>
</html>

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号