美文网首页Web前端之路
17、改进轮播图之功能封装

17、改进轮播图之功能封装

作者: 宁公子_5dce | 来源:发表于2019-08-21 20:43 被阅读1次

    之前我们做了一个简陋效果的轮播图,但是他有很多BUG,所以这次我们来改进一下,
    首先,就是各种功能的封装,将轮播图里的各种功能封装分离,不但便于维护,还有助于我们理清思路,并且让我们更加深刻的了解什么是面向对象:

    在做一个轮播图的时候会分为这几个步骤:

    1. 获取元素,通过DOM获取到HTML元素,记住,获取到的元素是对象

    2. 获取元素的css属性,通过获取元素的css样式来获得它的初始参数,获取得到的css样式同样也是对象

    3. 通过js操作css样式从而使元素改变位置,轮播,最基础的就是元素位置的改变,从而使其中图片变换

    4. 添加动画效果,通过js添加的动画效果拥有更好的兼容性和灵活性,

    通过以上几个步骤,是不是觉得轮播图瞬间容易了不少?其实DOM都是这几步:先获取,再操作,将其中的功能分离出来逐个击破,

    1. 获取元素:

    获取元素的方法有很多:
    通过id获取:document.getElementById();
    通过标签名获取:document.getElementsByTagName();
    通过类名获取:document.getElementsByClassName();
    这些方法各有优缺点,我选择了下面的这种方法:
    document.querySelectorAll()

                                    //获取元素节点对象
    //获取到的是一个类数组函数,所以使用时要进行遍历
    function $(selector){//css选择器
        return document.querySelectorAll(selector);
    }
    

    2. 获取css样式:为了更方便的使用,我选择获取内联或外部样式,用以下方法:

    getComputedStyle()是现在常用的方法,它的作用是一个元素的style属性,注意,style属性也是一个对象
    这个函数在IE8中不兼容,所以对IE8需要使用currentStyle方法
    为了方便,直接将其写成一个兼容函数让他自动判断

    //获取一个元素的css内联或外部样式
    function getStyle(el,attr){//元素节点对象,样式名
        if (typeof getComputedStyle == "undefined") {
            return el.currentStyle[attr];
        }else{
            return getComputedStyle(el,null)[attr];
        }
    }
    

    3.操作样式,添加动画:这个是最复杂的功能,我在这里需配合着获取css样式的getStyle()函数使用

    现在最新的设置js动画的方法,不在用一个值叠加距离,而是通过动画运动的时间和路程,直接将元素放在每一刻它应该在的位置
    得到起始位置b
    得到运动次数d
    设置当前次数t
    得到总路程c
    结果就是每一刻元素应该在c/d*t+b的位置上
    这种方法计算得出的动画效果更好,且规避了一些用距离叠加的方法产生的问题

    //设置动画效果
    function animate(el,option,allTime,callback){//元素节点对象,要设置的样式的对象集合,过渡时间,执行完毕后要执行的函数
    //得到起始位置
        var start = {};
        for(var attr in option){
            start[attr] = parseInt(getStyle(el,attr));
        }
        var d = parseInt(allTime/17);//得到运动次数
        var t = 0;//得到当前次数
        clearInterval(el.time);
        el.time = setInterval(function(){
            t++;
            for(var attr in option){    
                var b = start[attr];
                var c = option[attr] - b;//得到总路程
                if (t > d) {
                    clearInterval(el.time);
                    callback?callback():null;
                }else{
                    el.style[attr] = c/d*t+b+"px";
                }
            }
        },17)
    }
    

    这个功能不止可以移动元素,之前说过,js动画的特点就是灵活,所以这个函数可以做很多事情,如:
    改变位置:animate(obj,{left:400,top:300},300):将obj在0.3秒内移动到left为400px,top为300px的位置
    改变大小:animate(obj,{height:400},300):将obj的高度在0.3秒内增加或减小到400px
    以上三个功能都做好并理解之后,就可以思考怎样做轮播图了,

    完成轮播图:

    看十遍不如做一遍,将相应代码复制到编辑器中试一下,了解各行代码功能后再试着自己写一遍看看

    我设置的HTML页面:

    注意:类名和css样式一定要一致,

    <div class="box">
            <div class="lise">
                <div class="img"style="background: red">1</div>
                <div class="img"style="background: purple;">2</div>
                <div class="img"style="background: blue">3</div>
            </div>
            <div class="btn">
                <button class="item bgcolor"></button>
                <button class="item"></button>
                <button class="item"></button>
            </div>
            <button class="btn1 onLeft">向左</button>
            <button class="btn1 onRigth">向右</button>
        </div>
    

    我设置的内联css样式:

    注意:将其放在style标签中或者放在外部引用

            .box{
                width: 400px;height: 200px;position: relative;
                border: 2px solid #000;box-shadow: 0px 0px 5px red;
                margin: 100px auto;
            }
            .lise{
                width: 1200px;height: 100%;position: absolute;top: 0px;
            }
            .img{
                width: 400px;height: 200px;float: left;
                color: #fff;text-align: center;font-size: 50px;line-height: 200px;
            }
            .btn{
                position: absolute;bottom: 10px;left: 50%;transform: translateX(-50%);
            }
            .item{
                width: 15px;height: 15px;display: block;float: left;outline: none;
                background: #fff;margin: 0px 10px;border-radius: 50%;
            }
            .bgcolor{
                background: #999;
            }
            .btn1{
                width: 40px;height: 100px;background: rgba(0,0,0,0.5);position: absolute;
                color: #fff;top: 50%;transform: translateY(-50%);outline: none;
            }
            .onLeft{
                left: 0px;
            }
            .onRigth{
                right:0px;
            }
    

    用来设置轮播图的JS代码:

    注意:JS代码应该写在script标签中,上面写好的三个功能记得添加进来,如果写在外部,记得引用进来,引用的script标签一定要写在轮播图的script标签前面
    具体的各行代码的介绍都在注释里,为了简化代码所以将重复的代码放在函数中调用,如果不明白可以将其重新放入函数调用的位置测试,

    var item = $(".item"),box = $(".box"),lise = $(".lise"),onLeft = $(".onLeft"),onRight = $(".onRigth");
    
            //自动轮播
            var time = setInterval(next,3000);
            box[0].onmouseover = function(){//鼠标进入
                clearInterval(time);//关闭定时器
            };
            box[0].onmouseout = function(){//鼠标移出
                time = setInterval(next,3000);//重新开启定时器
            };
    
            //div的动画
            num = 0;//用来判断是第几张图
            onLeft[0].onclick = function () {//点击向左
                num = num<=0?2:--num;
                move();//调用下面的move函数
            };
            onRight[0].onclick = function () {//点击向右
                num = num>=2?0:++num;
                move();
            };
            for (var i = 0; i < item.length; i++) {//点击小圆点
                item[i].index = i;
                item[i].onclick = function (){
                    num = this.index;//为了保证深色小圆点是当前图片,将下标给num
                    move();
                };
            }
    
            function next(){
                num = num>=2?0:++num;
                move();
            }
    
            function move(){//将各事件中重复的代码放在一个函数中以供调用
                for(var j = 0;j<item.length;j++){//用类名改变小圆点的颜色,使对应图片的小圆点变色
                    item[j].className = "item";
                }
                item[num].className = "item bgcolor";
                animate(lise[0],{left:num*-400},300)//执行的动画
            }
    

    相关文章

      网友评论

        本文标题:17、改进轮播图之功能封装

        本文链接:https://www.haomeiwen.com/subject/yngisctx.html