原生JS实现轮播图

原生Js实现轮播图

前言

最近决心重新学习一次js,打牢基础,先从最常见的轮播图开始。

一、轮播图是什么?

顾名思义,就是轮流播放的图片,多应用在电商平台的海报,当我们进入一个网页中,轮播图一般是是最醒目的。

二、Html+Css

因为我们主要是实现滚动的功能,html和css就简单的说一下,轮播图一般包括三块内容,轮播的海报,海报两边的箭头,底部的圆圈。如下图:
在这里插入图片描述

1.html结构

轮播的图片可以放在ul列表当中,两侧的箭头用a标签,底部的圆圈用ol列表,放到一个 div标签中。
箭头和圆圈是通过雪碧图引入。

 <div class="slideshow">
        <ul>
            <li><a href="#"><img src="./img/1.jpg" alt=""></a></li>
            //...
        </ul>

        <div class="nav">
            <ol class="circle">
            //ol 中的li使用js动态生成,这样便于后期的维护
            </ol>
            <a href="javascript:;" class="left"></a>
            <a href="javascript:;" class="right"></a>
        </div>
    </div>

2.css

轮播图一定不止一张,我们可以观察到轮播图变化的时候,方向是左右变换,因此我们就需要将所有图片放到一行上面,这时候只需要改变父容器的宽度就可以。

.slideshow ul{
    position: absolute;
    width: 600%;
    height: 100%; // 可以省略
}

为了方便定位圆圈以及箭头的位置,我们可以先在htmll中写上 li标签,等定位好以后在删除。剩下的就是雪碧图的应用了

三、 Js

1.做出鼠标移动到轮播图区域中箭头显示的效果

要实现这一效果,只需要将对应选择器的样式从 display:block
改为 display:none就可以,要复原的话,当鼠标离开区域的时候在将属性改回来就行。有1个知识点需要注意:

  • 在进行事件绑定,鼠标移入:mouseenter 鼠标移除:mouseleave
window.addEventListener("load", function(){
// load 目的是为了让页面加载完成之后,在加载js
    var left = document.querySelector('.left');
    var right = document.querySelector('.right');
    var slideshow = document.querySelector('.slideshow');
    //slideshow 是整个轮播图的父容器
    slideshow.addEventListener('mouseenter', function(){
        left.style.display = 'block';
        right.style.display = 'block';
    })

    slideshow.addEventListener('mouseleave', function(){
        left.style.display = 'none';
        right.style.display = 'none';
    })
})

2.动态生成圆圈

要动态生成圆圈,必须要和图片的数量进行绑定,就要获取ul标签,通过ul.children.length来得到圆圈的数量

    var ul = document.querySelector('ul');
    var ol = document.querySelector('.circle');

    for(var i = 0; i < ul.children.length;i++){
        //创建li
        var li = document.createElement('li');
        //将li插入到 ol 当中
        ol.appendChild(li);
        //给 第一个 li 绑定样式
        ol.children[0].className = 'current';
    }

3.点击箭头让图片动起来

要让图片向左动起来,就必须要写一个动画函数实现这一功能,这一函数放到最后名字叫做 animate
每次要移动一整张图片,图片的宽度一般就是整个区域的宽度,我们可以获取区域的宽度进行移动。
图片向右动起来,原理相同

     // offsetWidth 水平方向 width + 左右padding + 左右border-width
     // offsetHeight 垂直方向 height + 上下padding + 上下border-width
     var slideshowWidth = slideshow.offsetWidth;
     var  num = 0;
    	right.addEventListener('click', function(){
    	//当最后一张图片播放完之后,另num = 0;从第一张开始播放
        if(num == ul.children.length - 1){
        //注意:在返回第一张图片的时候,不仅num要变成0,ul的定位也要变成0,第一张图片。
        //否则:图片会从 第四张,第三张,第二张,一直往回倒,看起来很不自然
        	ul.style.left = '0px';
            num = 0;
        }
        // 鼠标点击一次,num + 1
        num ++;
        //调用animate函数
        animate(ul, - num * slideshowWidth);
    })

但是我们可以注意到一个问题,当最后一张图片播放之后会出现一个空白期,再次点击后会直接跳到第二张图片,看起来不舒服,因此我们可以将第一张图片复制一下放到四张图片的后面,而这张图片的li不能在圆圈之前创建,否则元圆圈的数量会多出来一个。

//复制第一张图片
//注意:克隆第一张图片的时候,一定要将后代一起克隆,只复制 li 是没用的,我们要的是 其中的 img
    var first = ul.children[0].cloneNode(true);
    ul.appendChild(first);

4.实现点击圆圈的时候图片变换

这部分代码放在第二步的for循环中,这一步其实在第二步之后更为方便。
点击圆圈图片变换,本质也是调用了animate函数,因此为了计算移动的距离,必须要定义圆圈的索引。此时用到了setAttribute()方法,添加指定的属性并为其赋指定的值

//圆圈的索引 index
        li.setAttribute('index',i);
        //排他思想
        li.addEventListener('click',function(){
            //干掉所有人
            for(var i=0;i < ol.children.length;i++){
                ol.children[i].className = '';
            }
            //留下我自己
            this.className = 'current';
            //点击圆圈,移动图片 移动距离 索引 * 宽度
            var index = this.getAttribute('index');

            animate(ul, - index * slideshowWidth);

5.解决点击箭头时,图片与圆圈不匹配的问题

同样是排他思想,可以定义一个方法,在箭头事件中进行调用
注意:先 ++/–,在判断,和先判断在++/–有细微的差别。

function circleChange(){
        for(var i = 0; i < ul.children.length;i ++){
            ol.children[i].className = '';
            ol.children[circle].className = 'current';
        }
    }
//右侧箭头
		circle ++;
        if(circle == ol.children.length){
            circle = 0;
        }
        circleChange();
//左侧箭头
		circle --;
        if(circle < 0){
            circle = ol.children.length - 1;
        }
        circleChange();

再全局定义一个circle变量。

6.自动播放功能

自动播放功能相当于手动点击右箭头的点击事件

var timer = setInterval(function(){
        //手动调用点击事件
        right.click();
    },2000)

鼠标移入停止自动播放,因为之前写过鼠标移入移出事件,所以直接将代码加入到其中就行

//删除定时器
clearInterval(timer);
        timer = null; //清除定时器

鼠标移出继续开始

// timer 之前不能加 var 否则当鼠标移出之后会图片会加速
timer = setInterval(function(){
            //手动调用点击事件
            right.click();
        },2000)

end:animate动画函数

function animate(obj,target,callback){
// obj 是移动的对象 target 移动的距离 callback 回调函数
    clearInterval(obj.timer);  //清除定时器,放在重复调用
    obj.timer = setInterval(function(){
        // 步长值取整 向上取整 Math.ceil
        // var step = Math.ceil((target - obj.offsetLeft)/ 10);
        var step = (target - obj.offsetLeft) / 10;
        step = step > 0 ? Math.ceil(step) : Math.floor(step);
        if(obj.offsetLeft == target){
            clearInterval(obj.timer);
            if(callback){
                callback();
            }
        }
        obj.style.left = obj.offsetLeft + step + 'px';
    },20)
}

总结

Js轮播图的学习,学习到了setIntervalclearInterval定时器的使用,offsetWidth的用法等另思维更加清晰,对之前学习的基础语法进行了巩固。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值