无缝轮播

一、实现的功能:

1. 进入页面,轮播图自动向右切换

2. 鼠标悬停在轮播图部分时,轮播图停止切换,鼠标离开继续自动切换

3. 鼠标悬停在下方的小圆点上时,自动切换到对应的图片

4. 鼠标点击向左或向右按钮时,图片会向左或向右切换

效果图如下:

二、无逢轮播图实现原理:

所谓无逢轮播,就是几张图片向左或者向右切换,使最后一张图片和第一张图片首尾相连

第一张图片和最后一张图片之间的切换,也像相邻的图片之间的切换一样,实现几张图片左右滚动切换的效果

那么,问题来了

怎样使第一张图片和最后一张图片首尾相边呢?

我是这样做的

首先,需要一个div容器来包裹这个轮播图部分,我给这个容器添加了类名carouselContainer,这个容器的宽度和高度设置为图片的宽度和高度,我设置的是500px* 300px,还需要设置一个属性:overflow : hidden;

然后需要一个ul标签来放置多张图片,ul标签的ID为carousel

ul标签中放置多个li标签,每个li标签中都有一个img标签,用来放置图片,这几个标签向左浮动,在实现图片切换的时候,只需要移动ul即可

这部分是重点!

如果有3张图片,那我需要4个li标签,前三个li标签中放的是这三张图片,最后一个li中放的是第一张图片

如果有4张图片,那就需要5个li标签,前4个li标签放的是这4张图片,最后一个li中放的是第一张图片    以此类推

在这里,我就以3张图片为例啦!

为了方便理解,画了个草图

首先,容器中显示的是第一张图片,即 索引为0的 粉色部分,(0、1、2、3分别代表几张图片的索引值)向右切换时显示的应该是0、1、2、0、1、2...

那么3有什么作用呢?

这里就是重点中的重点啦

当图片切换到2时,下一张是3,这时再切换时,切换到3

当前图片是3,3和1是同一张图征,再切换应该切换到2

如果当前图片是3,同时又要向右切换,我们就把整个ul的margin-left设置为0,然后再让整个ul向左移动,移动到1(这里我们以为看到的是第一张图片,其实是因为第一张图片和最后一张图片是一样的,我们这时看到的是最后一张图片)

如果当前图片是0,同时又要向左切换,我们就把整个ul的margin-left设置为3*每张图片的宽度,再让整个ul向右移动,移动到2

这样就实现了第一张图片和最后一张图片的首尾相连。

好了,原理就是这样了

三、具体的代码实现

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <title>无缝轮播图</title>
  <script src="https://lib.baomitu.com/jquery/3.4.1/jquery.js"></script>
<style type="text/css">
    * {
        margin: 0;
        padding: 0;
    }
    .container {
        width: 600px;
        margin: 0 auto;
        margin-top: 100px;
        text-align: center;
    }
    .carouselContainer {
        width: 500px;
        height: 300px;
        border: 1px solid #eee;
        margin: 0 auto;
        margin-top: 20px;
        overflow: hidden;
        position: relative;
        border-radius: 5px;
    }
    #carousel {
        font-size: 0px;
        display: flex;
    }
    .arrowItems {
        position: absolute;
        width: 100%;
        font-size: 60px;
        display: flex;
        top: 50%;
        justify-content: space-between;
        height: 60px;
        transform: translateY(-50%);
    }
    .arrowItems div {
        width: 30px;
        text-align: center;
        line-height: 46px;
        vertical-align: middle;
        background: rgba(0, 0, 0, 0.2);
        cursor: pointer;
        color: rgba(255, 255, 255, 0.4);
    }
    .arrowItems div:hover {
        background: rgba(0, 0, 0, 0.5);
        color: rgba(255, 255, 255, 0.6);
    }
    .dots {
        position: absolute;
        left: 50%;
        transform: translateX(-50%);
        bottom: 25px;
        background: rgba(255, 255, 255, 0.5);
        border-radius: 10px;
        padding: 3px;
    }
    .dot {
        width: 12px;
        height: 12px;
        background: #fff;
        float: left;
        border-radius: 6px;
        margin: 0 3px;
    }
    .current {
        background: red;
    }
    img{
        width:500px;
        height:300px;
    }
</style>
</head>

<body>

<div class="container">
    <h2>无缝轮播图</h2>
    <div class="carouselContainer">        
        <ul id="carousel">
            <li><img src="001.jpg"></li>
            <li><img src="002.jpg"></li>
            <li><img src="003.jpg"></li>
            <li><img src="004.jpg"></li>
            <li><img src="005.jpg"></li>
            <li><img src="001.jpg"></li>
        </ul>
        <div class="arrowItems">
            <div class="left"></div>
            <div class="right"></div>
        </div>
        <div class="dots">
            <div class="dot current"></div>
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
            <div class="dot"></div>
        </div>
    </div>
</div>

</body>
<script type="text/javascript">

    var picIndex = 0;
    //为小圆点绑定鼠标经过事件
    $('.dots div').mouseover(function(){
        picIndex = $(this).index();
        var left = -(picIndex) * 500 + 'px';
        //鼠标经过小圆点时,切换对应的图片
        $('#carousel').stop().animate({'margin-left': left});
        //当前小圆点为红色,其他为白色
        $(this).addClass('current').siblings().removeClass('current');
    });


    //自动播放
    autoplayCarousel();

    var timeId;
    function autoplayCarousel(){
        timeId = setInterval(function(){
            $('.arrowItems .right').click();
        }, 1000)
    }

    //右边按钮
    $('.arrowItems .right').click(function(){
        
        if(picIndex == $('#carousel li').length - 1) {
            picIndex = 0;
            $('#carousel').css({'margin-left': '0px'});
        }
        picIndex ++;
        var left = -(picIndex) * 500 + 'px';
        $('#carousel').stop().animate({'margin-left': left});

        //控制小圆点
        if(picIndex == $('#carousel li').length - 1) {
            $('.dots div').eq(0).addClass('current').siblings().removeClass('current');
        }else {
            $('.dots div').eq(picIndex).addClass('current').siblings().removeClass('current');
        }
    });
    //左边按钮
    $('.arrowItems .left').click(function(){
        
        if(picIndex == 0) {
            picIndex = $('#carousel li').length - 1;
            $('#carousel').css({'margin-left': -($('#carousel li').length - 1) * 500 + 'px'});
        }
        picIndex --;
        var left = -(picIndex) * 500 + 'px';
        $('#carousel').stop().animate({'margin-left': left});

        //控制小圆点
        if(picIndex == $('#carousel li').length - 1) {
            $('.dots div').eq(0).addClass('current').siblings().removeClass('current');
        }else {
            $('.dots div').eq(picIndex).addClass('current').siblings().removeClass('current');
        }
    });

    $('.carouselContainer').mouseover(function(){
        clearInterval(timeId);
    });
    $('.carouselContainer').mouseout(function(){
        autoplayCarousel();
    });
</script>
</html>

四、在实现这个无逢轮播图地过程中也学到了一些知识,顺便记录下来

1. 子盒子在父盒子里面水平垂直居中

垂直居中:

以前的垂直居中用的都是设置子盒子top: 50%; margin-top为负的子盒子高度的一半

这个方法有局限性,如果以后子盒子的高度变了,还需要再改一次子盒子的margin-top值

现在发现了一个完美的方式来设置子盒子在父盒子里面垂直居中:

给子盒子设置top: 50%; transform: translateY(-50%);

top是相对于父盒子的高度设置的,transform是相对于子盒子自身的高度设置的,这样,以后父盒子、子盒子的高度不管怎样变化,子盒子都会在父盒子里面垂直居中

水平居中也是一样的,设置left: 50%; transform: translateX(-50%);

 

2. 动画要先停止再动

在使用jquery的animate动画时,如果多次触发动画,会出现动画错乱的现象,比如轮播图中的小圆点,如果鼠标一直在上面来回切换,图片就会左右乱动

出现这个现象的原因就是前一个动画还没停止,又要执行下一个动画

解决办法很简单,就是先让上一个动画停止再执行下一个动画,执行动画前先停止上一个动画

即代码中的$('#carousel').stop().animate({'margin-left': left});

加stop()就解决这个问题了

3. 清除定时器

在这个轮播图的例子中我设置了定时器来使图片自动播放,当鼠标悬停在轮播图区域时,需要停止自动播放,在鼠标离开轮播图区域时,再开始自动播放

做法就是在需要自动播放时,设置定时器,给定时器绑定一个ID,var timeId = setInterval(function(){}, 1000);

在需要停止的时候通过clearInterval(timeId);来清除计时器

再需要自动播放时再通过timeId = setInterval(function(){}, 1000);来实现自动播放

这里需要注意的是,这个timeId要设置成一个全局变量,否则,如果每次自动播放时都写成var timeId = setInterval(function(){}, 1000);这里的timeId是一个新的变量,清除计时器时清除的也不是同一个计时器,这样就会出现播放错乱的现象,所以要设置成一个全局变量。

4. 图片放在一起时会有逢隙

图片放在一起时,中间会有逢隙,比如轮播图中,我给ul标签中的li设置了float: left; 向左浮动,但是图片之间会有一个逢隙,这样不好控制图片的移动。

网上的解决办法有很多,在这里,我采用了最简单的解决办法,就是给父盒子设置,font-size: 0px;

这样,图片之间就没胡逢隙了。

原文地址:https://www.cnblogs.com/mjtabu/p/11974888.html