【小河今学 | HTML + CSS + JS + JQ】轮播图

08.26 今天作业是做轮播图
最终效果如下:
在这里插入图片描述

一、布局

布局一共有三个部分:图片、切换按钮、分页器。
实现轮播的原理很简单,将图片排成一排,设置一个可使的窗口,窗口的大小为一张图片的大小,其余部分进行hidden,要切换到下一张图片时,将这一排的图片进行位移即可。
接下来是具体代码:

	<div class="carousel">
        <div class="pic">
            <img src="/images/carousel1.jpg" alt="">
            <img src="/images/carousel2.jpg" alt="">
            <img src="/images/carousel3.jpg" alt="">
            <img src="/images/carousel4.jpg" alt="">
            <img src="/images/carousel5.jpg" alt="">
        </div>
        <div class="prev"></div>
        <div class="next"></div>
        <div class="count">
            <ul>
                <li class="active"></li>
                <li></li>
                <li></li>
                <li></li>
                <li></li>
            </ul>
        </div>
    </div>
* {
    margin: 0;
    padding: 0;
}

.carousel {
    margin: 100px auto;
    width: 800px;
    height: 300px;
    overflow: hidden;
    position: relative;
}

.pic {
    width: 9999px;
    position: absolute;
    left: 0px;
    top: 0;
    cursor: pointer;
}

.pic img {
    width: 800px;
    height: 300px;
    float: left;
}

.prev,.next {
    width: 40px;
    height: 40px;
    background-size: 40px 40px;
    position: absolute;
    top: 130px;     /* 300/2 - 40/2 */
    cursor: pointer;
}

.prev {
    background-image: url(/images/l.png);
    left: 20px;
}

.next {
    background-image: url(/images/r.png);
    right: 20px;
}

.prev:hover,.next:hover {
    background-color: rgba(255, 255, 255, 0.8);
    border-radius: 50%;
}

.count {
    width: 120px;
    position: absolute;
    bottom: 20px;
    left: 340px;
}

.count ul li {
    list-style: none;
    width: 12px;
    height: 12px;
    background-color: #fff;
    opacity: 0.8;
    float: left;
    margin-right: 15px;
    border-radius: 50%;
    cursor: pointer;
}

.count ul li:last-child {
    margin-right: 0px;
}

.count ul li:hover {
    opacity: 1;
}

.count ul .active {
    background-color: #000;
}

二、逻辑

首先引入jq,接着将轮播封装一个方法move,这个方法我们在按钮前后切换和分页器切换时都能用到,所以进行封装。
因为要达到缓慢切入的效果,所以用到计时器,每10毫秒改变图片的left值。

function move(){
        clearInterval(timer)
        timer = setInterval(() => {
            // 改变pic的偏移
            var imgLeft = $('.pic')[0].offsetLeft;
            var imgWidth = $('.pic img')[now].offsetWidth;
            var nowSpeed = (-(now * imgWidth) - imgLeft) / 5;
            if(imgLeft <= -(now * imgWidth) + 5){   // 调整偏移
                imgLeft = -(now * imgWidth);
            }else{
                imgLeft = imgLeft;
            }
            $('.pic').css('left', imgLeft + nowSpeed + 'px')
            // console.log(imgLeft)
        }, 10);
    }

在这里插入图片描述
这里简单的画了一张图方便大家理解,也就是说当我们想要显示第二张图时,将pic定位向左移800px(也就是移第一张图的宽度),想要显示第三张图时,将pic定位向左移1600px(也就是移第一张图和第二张图的宽度),以此类推。
想要达到缓慢切入效果,也就是要让他进入的速度由大到小,也就是说让left移动的距离宽度由大到小。
这里举例从一张图切入到第二张图时,此时下标now为1,偏移值为0,宽度为800,我们需要的完整偏移是-800,也就是 -(now * imgWidth)为完整显示第二张需要达到的偏移值。假设我们缓慢偏移,第一次偏移了100px,其实偏移值为-100,还剩下700需要偏移,也就是( -(now * imgWidth)- imgLeft),为了达到缓慢偏移的效果,我们将偏移值除于一个数,来达到每次偏移距离越来越小。
在这里插入图片描述
在示例中,我们的每次偏移值都除于5,因此过程如下,当第一次偏移时,now=1,偏移值为0,宽度为800,( -(now * imgWidth)- imgLeft)/ 5 = 160px,第二次偏移时,now=1,偏移值为-160,宽度为800,( -(now * imgWidth)- imgLeft)/ 5 = 128px,第三次偏移时,now=1,偏移值为-288(-160 -128),宽度为800,( -(now * imgWidth)- imgLeft)/ 5 = 102.4px,以此类推……
在这里插入图片描述
我们在控制台输出一下nowspeed,可以看到确实是这样。
在这里插入图片描述
因此pic每次的偏移值为nowspeed + imgLeft,从而达到缓慢切入的效果。最后测试时注意到每次都没办法达到800偏移占满,因此加上了一个判断条件,让他在最后一小段偏移时直接占满。

确定好轮播方法后就很简单了,在前后切换上,只需要注意下标的变换即可。

// 点击next切换到下一张
    $('.next').click(function () { 
        now++;
        if(now == len){
            now = 0;
        }
        // console.log(len)
        $('.count li').eq(now).addClass('active').siblings().removeClass('active')
        move();
    }); 
    // 点击prev切换到上一张
    $('.prev').click(function () { 
        now--;
        if(now == -1){
            now = len - 1;
        }
        // console.log(now)
        $('.count li').eq(now).addClass('active').siblings().removeClass('active')
        move();
    });

分页器也是注意下标变化即可。

// 点击分页器跳转
    $.each($('.count li'),function (idx,item) {
        $(this).click(function () { 
            $(this).addClass('active').siblings().removeClass('active');
            now = idx;
            move();    
        });
    })

自动播放需要用到另一个定时器,每一秒钟切换下一张图,实际上就是调用了next的点击方法

// 自动播放
    var autoPlayer = setInterval("$('.next').click()",2000)

当鼠标悬停时,停止自动播放,当鼠标移出后继续自动播放

// 鼠标移入悬停
    $('.pic').mouseover(function () { 
        clearInterval(autoPlayer)
    });
    // 鼠标移出继续播放
    $('.pic').mouseout(function () { 
        autoPlayer = setInterval("$('.next').click()",2000)
    });

完整代码如下:

;(function($){
    // 定义计时器
    var timer = null;
    var now = 0;    // 当前图的下标
    var len = $('.pic img').length;    // 获取到当前图片数组长度

    // 点击next切换到下一张
    $('.next').click(function () { 
        now++;
        if(now == len){
            now = 0;
        }
        // console.log(len)
        $('.count li').eq(now).addClass('active').siblings().removeClass('active')
        move();
    }); 
    // 点击prev切换到上一张
    $('.prev').click(function () { 
        now--;
        if(now == -1){
            now = len - 1;
        }
        // console.log(now)
        $('.count li').eq(now).addClass('active').siblings().removeClass('active')
        move();
    });
    // 点击分页器跳转
    $.each($('.count li'),function (idx,item) {
        $(this).click(function () { 
            $(this).addClass('active').siblings().removeClass('active');
            now = idx;
            move();    
        });
    })
    // 自动播放
    var autoPlayer = setInterval("$('.next').click()",2000)
    // 鼠标移入悬停
    $('.pic').mouseover(function () { 
        clearInterval(autoPlayer)
    });
    // 鼠标移出继续播放
    $('.pic').mouseout(function () { 
        autoPlayer = setInterval("$('.next').click()",2000)
    });

    function move(){
        clearInterval(timer)
        timer = setInterval(() => {
            // 改变pic的偏移
            var imgLeft = $('.pic')[0].offsetLeft;
            var imgWidth = $('.pic img')[now].offsetWidth;
            var nowSpeed = (-(now * imgWidth) - imgLeft) / 5;
            if(imgLeft <= -(now * imgWidth) + 5){   // 调整偏移
                imgLeft = -(now * imgWidth);
            }else{
                imgLeft = imgLeft;
            }
            $('.pic').css('left', imgLeft + nowSpeed + 'px')
            console.log(imgLeft)
        }, 10);
    }
})(jQuery);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值