使用原生js以两种方式制作一个精美的轮播图(下)

5,067 阅读8分钟

展示界面 & github源码

(这里可以实现PC端模拟移动端左右滑动图片切换的效果)

前言

  • 如何用原生js实现一个简单的轮播图呢?前面我已经用一种方法实现了,可能有些小伙伴觉得那种方法写的轮播图有点low,不够炫酷。那么,那就请看看下面这种方法实现的轮播图吧!
  • 现在我就分享第二种使用原生js实现轮播图的方法,这种方法制作轮播图的原理主要是控制所有图片的display从而控制图片显现的,为none的全部隐藏,为block显现出来,再通过定时器(setInterval)函数来控制图片达到轮播的效果。
  • 这种方法是我在查阅资料的时候没有看到的轮播图实现思路,希望能给以后想写轮播图的小伙伴一点帮助。

需求分析

  • 循环播放多张图片
  • 鼠标点击轮播图下面的指示点可以跳转到对应的图片,跳转结束后,再进行循环播放。
  • 可以手动左右切换图片,并且指示点也会进行相应的变化。

实现原理

  • 原理主要是让所有的图片都在一个大盒子box-imgs里面。控制每一张照片float为left,就可以让所有图片重叠在一起并且都在这个大盒子box-imgs里;然后再控制所有图片的display值从而控制图片显现的,要显现出来的图片display值为block,其他所有图片display值都为none;
  • 而图片轮播的效果就可以通我们熟悉的定时器(setInterval)函数,每过一段时间改变图片的display值从而控制图片达到轮播的效果,我们还可以通过给显现出来的图片添加类名来增加酷炫的动画效果。

实现过程&思路

HTML部分

<div class="box-cirs-imgs">
    <div class="box-imgs">
        <ul class="imgs">
            <li><img src="./images/App-4-D.jpg"></li>
            <li><img src="./images/app-2-D.jpg"></li>
            <li><img src="./images/App-3-D.jpg"></li>
            <li><img src="./images/App-1-D.jpg"></li>
        </ul>
    </div>
    <ul class="box-cirs"></ul>
</div>
  • 大盒子box-cirs-imgs包含着装载所有图片的盒子box-imgs和指示点类名为box-cirs的ul结构。盒子box-imgs里包含着装载图片的ul、li结构。这里结构很简单,我就不细讲了。
  • 注意:html部分我没有写指示点的结构,后面我会通过js来添加指示点。

CSS部分

.box-cirs-imgs {
        position: relative;
}
.box-imgs {
    display: inline-block;
    background-color: rgb(165, 165, 165);
}
.imgs li {
    width: 100%;
    float: left;
}
img {
    width: 100%;
    height: 100%;
}
.ani {
    animation: ani_img .5s ease 1;  //给当前显示的图片添加一个类名,让轮播效果更酷炫
}
@keyframes ani_img{//动画脚本
    0%{
        opacity: 0;        
    }
    50%{
        opacity: 0.5;        
    }
    100%{
        opacity: 1;        
    }
}
.box-cirs {
    position: absolute;
    bottom: 10px;
    right: 50%;
    transform: translateX(50%);
}
.box-cirs li {
    display: inline-block;
    width: 8px;
    height: 8px;
    margin-right: 5px;
    border-radius: 50%;
    cursor: pointer;//改变鼠标触及区域时光标样式
}
.active {
    background-color: #00bebe;//高亮的指示点
}
.quiet{
    background-color: #00263c;//指示点的默认样式
}
  • 注意:虽然上面html结构中没有写指示点的结构,但是css样式中却要写指示点的样式;添加了类名ani用来添加动画效果,让轮播效果更酷炫!

JS部分

  • 用js来给页面动态添加小圆点
//这里我们先添加小圆点,让页面显示完整,之所用js添加小圆点,
是因为小圆点的数量应该由图片张数决定的。
    for (var i = 0; i < len; i++) {
        var c_li = document.createElement('li');
        jsCirs_ul.appendChild(c_li);
    }
  • 将会在下面用到的html中的对象和一些变量
/*获取HTML中的对象*/
const jsImgs_box = document.querySelector('.box-imgs');
const jsImgs_ul = document.querySelector('.imgs');
const jsImg = jsImgs_ul.children;
const jsCirs_ul = document.querySelector('.box-cirs');
const jsCir = jsCirs_ul.children;
//定义一些变量
var len = jsImg.length;//图片的张数
var timer = null;                     //初始化一个定时器
var picN = 0;                         //当前显示的图片下标
var cirN = 0;                         //当前显示图片的小圆点下标
hold = false;                           //初始化按下时的状态,开关变量
let stratPointX = 0;                    //初始化按下时x轴坐标
let endsetX = 0;                        //初始化按键离开时x轴坐标
  • 首先我们来理解一下显现出来的图片是怎么设计的,现在就让我们来定义一个 Roll()显现效果函数。
 //定义一个函数,通过传进来的要显示的图片的下标来控制显示,会在autoRun函数中调用
    function Roll(index, num) {
        for (var i = 0; i < len; i++) {
            jsImg[i].style.display = 'none';
            jsCir[i].className = 'quiet';
            jsImg[i].className = '';
        }
        jsImg[index].style.display = 'block';
        jsCir[num].className = 'active';
        jsImg[index].className = 'ani';
    }
  • 定义好了Roll()函数那我们也就完成了最关键的一步,接下来我们要做的是让图片自动轮播。所以在这里我们先定义一个autoRun()自动轮播函数。
//设置自动播放函数autoRun(),只要传入当前的图片和圆点的索引值就会从此处开始自动轮播
    function autoRun(pic, cir) {
        // 当调用autoRun()函数,传入的实参不是pic = 0,cir = 0;时,执行下面语句
        if (pic != 0) {//当调用autoRun()传进来的实参不为0的时候的情况
            //当点击最后一个圆点时,要先显示最后一张图片,再从第一张重新开始轮播
            if (pic === len - 1) {
                Roll(pic, cir);
                pic = 0;
                cir = 0;
                time(pic, cir);//封装一个time()函数,减少代码复用
            } else {//当点击第二、三个圆点时,显示当前点击圆点的图片和高亮,再进行循环
                Roll(pic, cir);
                ++pic;
                ++cir;
                time(pic, cir);
            }
        } else {//当页面加载时,预先定义好的pic = 0,cir = 0实参会传进来,执行下列语句,会自动轮播
            Roll(pic, cir);//先显示传入实参的图片和圆点的高亮
            ++pic
            ++cir
            time(pic, cir);
        }
    }
  • 自动轮播是由定时器setInterval控制的,下面是封装的time()函数
//封装自动播放函数autoRun里的定时器内参数递增,
        function time(pi, ci) {
            timer = setInterval(function () {
                Roll(pi, ci);
                pi++;
                ci++;
                if (pi > len - 1) {//当第四张图片显现时要回到第一张图片轮播
                    pi = 0;
                }
                if (ci > len - 1) {
                    ci = 0;
                }
            }, 7200)
        }
  • 当页面加载时就调用autoRun函数自动播放,传入预先定义好的pic = 0,cir = 0实参
window.onload = autoRun(picN, cirN);
  • 上面已经实现了自动轮播的功能,现在来添加指示点点击切换图片功能
//用for循环给每个圆点绑定一个点击事件
for (var j = 0; j < len; j++) {
    jsCir[j].index = j;//给每个圆点一个索引值
    //当点击小圆点是高亮
    jsCir[j].onclick = function () {
        clearInterval(timer)//每次运行该函数必须清除之前的定时器!
        var i = this.index;  //将当前圆点的index索引值传给i
        autoRun(i, this.index)  //传入实参i,this.index,e,调用自动轮播函数autoRun()
    }
}
  • PC端仿造移动端增加轮播图触摸滑屏事件,通过监控鼠标按下时坐标横向的位置,和鼠标放开时坐标的变化来判断要不要触发滑屏事件。
  • 这种方法在查阅资料后个人觉得pc端并不常见,所以还挺有价值的,希望能对各位看官有所帮助。
// 鼠标摁下时执行的事件
    jsImgs_box.onmousedown = function (e) {
        e.preventDefault();
        //注意:preventDefault()阻止轮播图图片被拖拽的默认行为
        hold = true;
        clearInterval(timer);
        // console.log('你点击了鼠标');
        stratPointX = e.clientX;
    }
    //其实这里还可以添加一个鼠标移动事件onmousemove,各位看官可以添加试试。
//放开鼠标执行的事件
    jsImgs_box.onmouseup = function (e) {
        // console.log('你放开了鼠标');
        endsetX = e.clientX;
        if (hold) {
            for (var j = 0; j < len; j++) {
                jsImg[j].index = j;
            }
            if ((stratPointX - endsetX) > 400) {
                moveleft();//封装了左移函数
            } else if ((endsetX - stratPointX) > 400) {
                moveright();//封装了右移函数
            } else {// bug 修复  如果点击了会清除定时器,这里要重新开启一下
                n = document.querySelector('.ani').index
                autoRun(n, n);
            }
            hold = false;
        }
    }
    // 图片左移函数
    function moveleft() {
        var i = document.querySelector('.ani').index - 1;
        if (i < 0) {//bug处理,如果当前显现的图片是第一张时,移动后应该跳转到第四张图片
            i = 3;
        }
        autoRun(i, i);
    }
    //图片右移函数
    function moveright() {
        var i = document.querySelector('.ani').index + 1;
        if (i > 3) {//bug处理,如果当前显现的图片是第四张时,移动后应该跳转到第一张图片
            i = 0;
        }
        autoRun(i, i);
    }
  • 注意:如果不在点击时给jsImgs_box添加preventDefault(),window网页里图片的默认拖拽行为会影响到onmousemove、onmouseup事件的执行。

总结

一直说要写第二种原生JS方法实现轮播图,现在终于完成了,总的来说轮播图并不难实现,但是如果要写却有很多方法,用原生js、纯css、RecyclerView、还可以使用jquery插件...总之方法很多,但是如果是像我这样的前端入门新手建议还是可以用原生JS手写一个轮播图,这样即可以锻炼一下js,还可以掌握一个网页常用的组件手写方法,一石二鸟,何乐而不为呢?好啦,这篇文章到这里已经写完了,如果各位大佬发现我的方法还有缺陷,欢迎楼下评论告诉我,毕竟对于我这样的新手来说,需要不停的发现问题!不停的改进!才能成长成为像各位看官一样的大牛!