js实现轮播图

js实现轮播图

1.普通轮播图

html

页面展示区为wrap,里面第一部分是大图,第二部分是索引点,第三部分是向前向后按钮。

<div class="wrap">
    <ul class="list">
        <li class="item active"><img src="./images/images/1.jpg"></li>
        <li class="item"><img src="./images/images/2.jpg"></li>
        <li class="item"><img src="./images/images/3.jpg"></li>
        <li class="item"><img src="./images/images/4.jpg"></li>
        <li class="item"><img src="./images/images/5.jpg"></li>
    </ul>
    <ul class="pointList">
        <li class="point active"></li>
        <li class="point"></li>
        <li class="point"></li>
        <li class="point"></li>
        <li class="point"></li>
    </ul>
    <button class="button prev"><</button>
    <button class="button next">></button>
</div>
css

布局:让五张照片叠在一起。

<style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: content-box;
        }
        .wrap {
            position: relative;
            width: 400px;
            height: 320px;
        }
        .list {
            width: 400px;
            height: 320px;
            list-style: none;
            position: relative;
        }
        .item {
            width: 400px;
            position: absolute;
        }   /*五张照片叠在一起。*/

        .button {
            width: 20px;
            height: 40px;
            position: absolute;
            top: 140px;
            z-index: 100; /*按钮显示优先级最高*/
            opacity: 0;
        }
        .prev {
            left: 5px;
        }
        .next {
            right: 5px;
        }
        .item.active {
            z-index: 10;   /*哪张图片被加了active,哪张图片的显示优先级最高。*/
        }
        .pointList {
            list-style: none;
            position: absolute;
            right: 10px;
            bottom: 10px;
            z-index: 30;  /*要设置z-index,否则默认为0,显示不出来。*/
        }
        .point{
            width: 20px;
            height: 20px;
            background-color: darkred;
            border-radius: 50%;
            float: left;
            margin-left: 5px;
            cursor: pointer;
        }
        .point.active {
            background-color: red;
        }

    </style>
JavaScript

原理:给哪张图片添加类active,哪张图片就在最上面。(设置z-index)

<script>
        window.onload = function(){
            //1.获取元素
            var wrap = document.getElementsByClassName('wrap')[0];
            var items = document.getElementsByClassName('item');
            var prev = document.getElementsByClassName('prev')[0];
            var next = document.getElementsByClassName('next')[0];
            var pointList = document.getElementsByClassName('pointList')[0];
            var points = pointList.getElementsByClassName('point');

           /*2.按钮控制的向左向右*/   
           /*整个逻辑主要是在操作index*/
            var index= 0;  /*index表示第几张图片在展示。*/
            var clearActive = function(){
                for(var i = 0;i<items.length;i++)
                {
                    items[i].className = 'item';
                    points[i].className = 'point'; /*先清除掉所有的active*/
                }
            };
            var goIndex = function (){
                clearActive();
                items[index].className = 'item active';/*设置第index张图片有active这个类名。*/
                points[index].className = 'point active';/*设置第index个索引点有active这个类名*/
            };

            var goNext = function(){
                if(index >= 4)
                {
                    index = 0
                }else{
                    index++;
                }
                goIndex();
            };
            var goPrev = function(){
                if(index <= 0)
                {
                    index = 4
                }else{
                    index--;
                }
                goIndex();
            };
            next.onclick = function(){
                goNext();
            };
            prev.onclick = function(){
                goPrev();
            };




            /*3.索引点控制的轮播图*/
            for(var i=0; i<points.length;i++)
            {
                points[i].index = i;/*给point[i]一个index属性,表示索引点对应的图片的index*/
                points[i].onmouseover = function(){
                    index = this.index;
                    goIndex();
                }
            }

           /*4.定时器控制的轮播图*/
            var timer;
            var autoSlide = function() {
                timer = setInterval(function(){
                    goNext();
                },2000)
            };
            autoSlide();



            wrap.onmouseover = function(){
                clearInterval(timer);
                prev.style.opacity = '1';
                next.style.opacity = '1';

            };
            wrap.onmouseout = function(){
                autoSlide();
                prev.style.opacity = '0';
                next.style.opacity = '0';
            }
        }
    </script>

2.无缝滚动轮播

html
<div id="box">
    <div id="slider">
        <div class="item"><img src="./images/images/5.jpg"></div>
        <div class="item"><img src="./images/images/1.jpg"></div>
        <div class="item"><img src="./images/images/2.jpg"></div>
        <div class="item"><img src="./images/images/3.jpg"></div>
        <div class="item"><img src="./images/images/4.jpg"></div>
        <div class="item"><img src="./images/images/5.jpg"></div>
        <div class="item"><img src="./images/images/1.jpg"></div>
    </div>
    <span id="prev"><</span>
    <span id="next">></span>
    <ul id="nav">
        <li class="active"></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
    </ul>
</div>
css

#slider相对#box进行定位。

<style>
        * {
            padding: 0;
            margin: 0;
            box-sizing: content-box;
           
        }
        #box {
            width: 400px;
            height: 320px;
            position: relative;
            overflow: hidden;
        }
        #slider {
            width: 2800px;
            height:320px;
            position: absolute;
            left: -400px;
        }
        .item {
            width: 400px;
            height: 320px;
            float: left;
        }
        #prev {
            font-size: 2em;
            position: absolute;
            top: 140px;
            left: 2px;
            background-color: red;
            cursor: pointer;
            opacity: 0;
        }
        #next {
            font-size: 2em;
            position: absolute;
            top: 140px;
            right: 2px;
            background-color: red;
            opacity: 0;
            cursor: pointer;
        }
        #nav {
            position: absolute;
            bottom: 5px;
            left: 125px;
            list-syle: none;
        }
        #nav li {
            width: 15px;
            height: 15px;
            border-radius: 50%;
            background-color: #ccc;
            float: left;
            margin-left: 15px;
        }
        #nav li.active {
            background-color: red;
        }
    </style>
JavaScript

原理:slider相对box的定位left发生改变,每次移动的值是一张图片的宽度。

  1. 首先封装animate函数。animate函数是一个多目标缓冲运动框架。这个函数定义了对象obj朝向目标json的缓冲运动。
//获取非内联样式。
function getStyle(obj,name){
   if(obj.currentStyle){
       return oDiv1.currentStyle[name];
   }else{
       return getComputedStyle(obj,null)[name];
   }
}
//animate(odiv,{width: 100,height: 200,opacity: 100},)
//封装一个animate函数,用于动画。
function animate(obj,json,callback){
   clearInterval(obj.timer);
   obj.timer = setInterval(function(){
       for(var attr in json)
       {
           var isStop = true; //一开始假设所有属性都到了目标值,因为有好几个属性。这里是设置一个状态标志。
           var now;
           if(attr === 'opacity')
           {
               now = parseFloat(getStyle(obj,attr))*100;
           }
           else{
               now = parseInt(getStyle(obj,attr));
           }
           var speed = (json[attr]-now)/10;
           speed = speed>0?Math.ceil(speed):Math.floor(speed);/*Math.ceil():向上取整,Math.floor():向下取整。*/
           if(attr === 'opacity')
           {
               obj.style.opacity = (now + speed)/100;

           }else{
               obj.style[attr] = now +speed+'px';
           }

           if(now!== json[attr])
           {
               isStop = false; /*只要有一个不到目标值,就为false*/
           }
       }

       if(isStop)               /*所有的值都到了目标值才能清除定时器*/
       {
           clearInterval(obj.timer);
           if(callback){
               callback();
           }
       }
   },50)
}
  1. 通过调用animate函数,设置目标left为对应的值,就可以移动一次。要实现自动轮播,在外面加一个定时器就可以了。

    但实现难点在于:怎么实现无缝轮播。
    办法:
    在这里插入图片描述
    当图片1向前切换到图片5时,迅速切换到后面的图片5;
    当图片5向后切换到图片1时,迅速切换到前面的图片1。

            /*要实现自动轮播,就要给图片一个索引值*/
            var index = 0;
            /*一开始默认left是-400*/
            setInterval(function () {
                index++;
                animate(slider,{left: -400*(index+1)},function(){
                    if(index === 5)
                    {
                        slider.style.left = '-400px';/*每次运动完用回调函数判断index*/
                        index = 0;
                    }
                })
            }, 2000)
            //这样实现了向下一张的无缝轮播
    
             var timer;
             var index = 0;
             var slideNext = function(){
                 index++;
                 animate(slider,{left: -400*(index+1)},function(){
                     if(index === 5)
                     {
                         slider.style.left = '-400px';
                         index = 0;
                     }
                 })
             }
             var slidePre = function(){
                 index --;
                 animate(slider,{left: -400*(index+1)},function(){
                     if(index === -1)
                     {
                         slider.style.left = '-2000px';
                         index = 4;
                     }
                 })
             }
             timer = setInterval(slideNext,2000);
    
             box.onmouseover = function(){
                 animate(prev,{opacity:50});
                 animate(next,{opacity:50});
                 clearInterval(timer);
    
             };
             box.onmouseout = function(){
                 animate(prev,{opacity:0});
                 animate(next,{opacity:0});
                 timer = setInterval(slideNext,2000)
             };
    
             next.onclick = slideNext;
             prev.onclick = slidePre;
    
    1. 导航点的点击事件
      功能:导航点点击,left定位到对应的图片
      在这里插入图片描述
    for(var i= 0;i<lis.length;i++)
            {
                lis[i].idx = i;/*给每个导航点一个属性idx*/
                lis[i].onclick = function(){
                    index = this.idx;
                    animate(slider,{left:-400*(index+1)})
                }
            }
    
  2. 当图片发生变化,要对应的导航点变化。

          var change = function(){
                for(var i = 0;i<lis.length;i++)
                {
                    lis[i].className = '';
                }
                lis[index].className = 'active';
            }
            //将change方法在slideNext、slidePre和导航点击事件中调用。
    

    但是出现了问题: 当图片变化到index为5和-1时,图片是可以继续变化但是导航点并没有这个索引点。所以将这两个特殊情况列出来。

          var change = function(){
                for(var i = 0;i<lis.length;i++)
                {
                    lis[i].className = '';   //清除之前的active
                }
                if(index === 5)
                {
                    lis[0].className = 'active'
                }else if(index === -1)
                {
                    lis[4].className = 'active'
                }else{
                    lis[index].className = 'active';
                }
    
            } 
    
    优化

    如果还没运动到对应的位置,就频繁点击左右按钮,会出现意想不到的结果,所以要优化。
    实现功能:如果还在运动时,点击左右按钮时无效的
    是否在运动这个状态我们可以用true和false来标记。

    		var isMoving = false;
            var timer;
            /*要实现自动轮播,就要给图片一个索引值*/
            var index = 0;
            /*一开始默认left是-400*/
            var slideNext = function(){
                if(!isMoving){
                    isMoving = true;
                    index++;
                    change();
                    animate(slider,{left: -400*(index+1)},function(){
                        if(index === 5)
                        {
                            slider.style.left = '-400px';/*每次运动完用回调函数判断index*/
                            index = 0;
                        }
                        isMoving = false;
                    })
                }
            }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值