JS经典案例-无缝滚动轮播图(纯JS)

发布于:2022-11-05 ⋅ 阅读:(299) ⋅ 点赞:(0)

滚动轮播图

在JS初级阶段,轮播图是最基础最经典的案例,而相比于渐变轮播图,无缝滚动轮播图又要更难一点。渐变轮播图仅需要使用到点击事件、定时器等,而无缝滚动轮播图则需要考虑到 第一张>最后一张,最后一张>第一张的滚动切换。

效果图:

在这里插入图片描述

需求:

制作一个无缝滚动轮播图,轮播图会自动无缝滚动切换,当鼠标移到轮播图区域停止自动播放,鼠标移出后轮播图继续自动播放,拥有向左、向右点击切换功能和底部小圆点切换功能。

思路:
  1. 把几张图当成整体放在一个盒子里,使用浮动让所有图片一行排列,盒子宽度为图片宽度之和
  2. 外面套一层父级盒子设置为一张图的宽度,同时设置溢出隐藏
  3. 点击左/右切换时运用transform将整体向相应的方向移动
  4. 自动轮播巧妙运用过渡效果以及定时器的调用与清除
HTML结构

这里给放置图片的区域设置颜色来替代了图片

	<!-- 视角区域 -->
	<div class="box">
		<!-- 整体图片区域 -->
        <div class="wipper">
            <div style="background-color: red;">1</div>
            <div style="background-color: green;">2</div>
            <div style="background-color: brown">3</div>
            <div style="background-color: blue;">4</div>
            <div style="background-color: cadetblue;">5</div>
            <!-- 复制第一张图片,后面使第一张和最后一张无缝切换 -->
            <div style="background-color: red;">1</div>
        </div>
        <!-- 向左切换按钮 -->
        <div class="pre">&lt;</div>
        <!-- 向右切换按钮 -->
        <div class="next">&gt;</div>
        <!-- 底部小圆点 -->
        <div class="lis">
            <span class="current"></span>
            <span></span>
            <span></span>
            <span></span>
            <span></span>
        </div>
    </div>

css样式
		*{
            margin: 0;
            padding: 0;
        }
        .box{
            width: 600px;
            height: 300px;
            margin: 50px auto;
            overflow: hidden;
            position: relative;
        }
        .wipper{
            width: 3600px;/*设置为图片的总宽度*/
            height: 300px;
            position: absolute;
            left: 0;
        }
        .wipper div{
            width: 600px;
            height: 300px;
            float: left;
            text-align: center;
            font-size: 30px;
            line-height: 300px;
            color: #fff;
        }
        .pre,.next{
            width: 20px;
            height: 30px;
            line-height: 30px;
            text-align: center;
            color: #fff;
            background-color: rgba(0, 0, 0, 0.5);
            position: absolute;
            transform: translateY(-50%);
            cursor: pointer;
            display: none;    
        }
        .box:hover .pre{
            display: block;
        }
        .box:hover .next{
            display: block;
        }
        .pre{
            left: 0;
            top: 50%;
        }
        .next{
            right: 0;
            top: 50%;
        }
        .lis{
            text-align: center;
            border-radius: 5px;
            position: absolute;
            bottom: 0;
            left: 50%;
            transform: translateX(-50%);
        }
        .lis span{
            display: inline-block;
            width: 10px;
            height: 10px;
            border-radius: 50%;
            background-color: #ccc;
        }
        .lis span.current{
            background-color: greenyellow;
            
        }

JS代码

难点:
如何使图片在第一张时点击上一张,向左滚动切换到最后一张。
如何使图片在最后一张时点击下一张,向右滚动切换到第一张

		//获取元素
		var box=document.getElementsByClassName('box')[0]
        var wipper=document.getElementsByClassName('wipper')[0]
        var divs=wipper.getElementsByTagName('div')
        var pre=document.getElementsByClassName('pre')[0]
        var next=document.getElementsByClassName('next')[0]
        var lis=document.getElementsByClassName('lis')[0]
        var spans=lis.getElementsByTagName('span')
        //定义一个index保存当前图片索引
        var index=0
        //下一张按钮点击事件
        function nextClick(){
            //点击时index自增
            index++
            //给盒子过渡效果,向左移动
            wipper.style.transition='all .5s'
            wipper.style.transform='translateX('+(-index*divs[0].offsetWidth) +'px)' ;
            //判断如果到了最后一张
            if(index==divs.length-1){
                //初始化index=0
                index=0
                //设置定时器把最后一张变为第一张
                setTimeout(() => {
                    wipper.style.transform='translate(0,0)' ;
                    wipper.style.transition='none'
                }, 500);//定时器时间设置为500毫秒,与过渡时间相等
            }
            //小圆点变化
            for(var i=0;i<spans.length;i++){
            	//初始化类名
                spans[i].className=''
                //给相应图片对应的小圆点添加类名修改颜色
                spans[index].className='current'
            }
        }
        next.onclick=nextClick
        
        //上一张
        function preClick(){
            //点击时index自减
            index--
            //index自减==-1即第一张图片的上一张
            if(index==-1){
                //使图片转为最后一张
                wipper.style.transform='translateX('+(-5*divs[0].offsetWidth) +'px)' ;
                wipper.style.transition='none'
                //初始化index为倒数第二张
                index=4
                //初始化点击的过渡效果,使其执行完毕,不设置定时器会事件冲突
                setTimeout(() => {
                    wipper.style.transform='translateX('+(-index*divs[0].offsetWidth) +'px)' ;
                    wipper.style.transition='all .5s'
                }, 0);
            }else{
                //正常情况的切换
                wipper.style.transform='translateX('+(-index*divs[0].offsetWidth) +'px)' ;
                wipper.style.transition='all .5s'
            }
            //小圆点变化
            for(var i=0;i<spans.length;i++){
                spans[i].className=''
                spans[index].className='current'
            }
        }
        pre.onclick=preClick

        //自动轮播
        var timer=setInterval(nextClick,1000);

        //小圆点的点击事件
        for(var i=0;i<spans.length;i++){
        	//设置自调用函数并传入i值,避免点击时循环已经到了最大值结束
            (function(i){
                spans[i].onclick=function(){
                    //获取当前点击圆点父级元素的所有子元素span
                    var allSpans=this.parentNode.children
                    //循环遍历,清空所有小圆点的类名
                    for(var j=0;j<allSpans.length;j++){
                        allSpans[j].className=''
                    }
                    //给当前点击的小圆点添加类名
                    this.className='current'
                    //将i赋值给index
                    index=i
                    //设置图片切换到点击的小圆点所对应的图片
                    wipper.style.transform='translateX('+(-index*divs[0].offsetWidth) +'px)' ;
                    wipper.style.transition='all .5s'
                }
            })(i)
        }
        // 移入box,清除定时器
        box.onmouseenter=function(){
            clearInterval(timer)
        }
        // 移出box,重新调用定时器
        box.onmouseleave=function(){
            timer=setInterval(nextClick,1000)
        }



网站公告

今日签到

点亮在社区的每一天
去签到