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

之前我们做了一个简陋效果的轮播图,但是他有很多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样式一定要一致,

1
2
3

我设置的内联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

你可能感兴趣的:(17、改进轮播图之功能封装)