jquery滑动效果的运动模块封装

效果图css

move.htmlhtml

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>move</title>
    <link rel="stylesheet" href="../css/base.css">
    <link rel="stylesheet" href="../css/move.css">
</head>
<body>
    <div class="slider">
        <div class="box" id="box"></div>
        <div class="box" id="box2"></div>
    </div>
    <button class="btn back fl">&lt;</button><button class="btn forw fl">&gt;</button>

    <script src="../js/jquery.js"></script>
    <script src="../js/transition.js"></script>
    <script src="../js/move.js"></script>
    <script>
        var box=$("#box"),
            box2=$("#box2"),
            back=$(".back"),
            forw=$(".forw");

        //接收消息
        box.on("move moved",function(e,elem){
            console.log(e.type);
            console.log(elem);
        })
        box.move({
            css3:true,
            js:true
        });
        box2.move({
            css3:true,
            js:true
        });
        forw.on("click",function(){
            box.move("x",-200);
            box2.move("x",0);
        });
        back.on("click",function(){
            box.move("x",0);
            box2.move("x",200);
        });
    </script>
</body>
</html>

base.css http://www.noobyard.com/article/p-pdzklbfz-by.htmljquery

move.csscss3

    /*提取出过渡样式,可公用*/
    .transition{
        -webkit-transition:all .5s;
        -moz-transition:all .5s;
        -ms-transition:all .5s;
        -o-transition:all .5s;
        transition:all .5s;
    }
    .box{
        position: absolute;
        width:200px;
        height:100px;
        background-color: pink;
        top:0;
        left:0;
    }
    .btn{
        width:100px;
        height:20px;
        
    }
    .back{
        margin-left:100px;
    }
    #box2{
        left:100%;/*父容器宽度*/
        background-color:#abcdef;
    }
    .slider{
        position: relative;
        width:200px;
        height:100px;
        border:2px solid #ccc;
        margin-left:100px;
        overflow:hidden;
    }

transition.js http://www.noobyard.com/article/p-aawuejuc-w.htmlweb

move.jside

(function($){

    "use strict";

    var transition=window.mt.transition;//transitionend
    var isSupport=window.mt.isSupport;//true

    var init=function(elem){
        this.elem=elem;
        this.curX=parseFloat(this.elem.css("left"));
        this.curY=parseFloat(this.elem.css("top"));
    }
    var to=function(x,y,callback){
        x=(typeof x==="number"?x:this.curX);//x若是不是数字,则只对y轴操做
        y=(typeof y==="number"?y:this.curY);//y若是不是数字,则只对x轴操做
        if(this.curX===x && this.curY===y) return;
        //已经到达目的地,避免重复执行
        
        this.elem.trigger("move",[this.elem]);//发送开始运动的消息,并传递运动的元素
        if(typeof callback==="function") callback();

        this.curX=x;
        this.curY=y;
    }

// silent
    var silent=function(elem){
        // call的做用主要是为了改变this指向
        // 不加call, 直接调用init函数, 那么的this指向了init
        // 添加call, 让init函数的this指向Silent对象
        init.call(this,elem);
        this.elem.removeClass("transition");//确保没有动画效果,写在构造函数里面只会执行一次
    }
    silent.prototype.to=function(x,y){
        var self=this;//改变函数内部this指向为当前对象

        to.call(this,x,y,function(){
            self.elem.css({
                left:x,
                top:y
            });
            self.elem.trigger("moved",[self.elem]);//发送结束运动的消息
        });
    }
    silent.prototype.x=function(x){
        this.to(x);
    }
    silent.prototype.y=function(y){
        this.to(null,y);
    }

//css3
    var css3=function(elem){
        init.call(this,elem);
        this.elem.addClass("transition");

        //设置top和left,避免因css中没有设置形成动画失效
        this.elem.css({
            left:this.curX,
            top:this.curY
        });
    }
    css3.prototype.to=function(x,y){
        var self=this;//改变函数内部this指向为当前对象

        to.call(this,x,y,function(){
            self.elem.off(transition).one(transition,function(){
                self.elem.trigger("moved",[self.elem]);
            });

            self.elem.css({
                left:x,
                top:y
            })
        });

    }
    css3.prototype.x=function(x){
        this.to(x);
    }
    css3.prototype.y=function(y){
        this.to(null,y);
    }

//js
    var js=function(elem){
        init.call(this,elem);
        this.elem.removeClass("transition");//transition会致使js动画失效
    }
    js.prototype.to=function(x,y){
        var self=this;//改变函数内部this指向为当前对象

        to.call(this,x,y,function(){
            self.elem.stop().animate({
                left:x,
                top:y
            },function(){//这里的回调表明动画结束执行
                self.elem.trigger("moved",[self.elem]);
            });
        });
    }
    js.prototype.x=function(x){
        this.to(x);
    }
    js.prototype.y=function(y){
        this.to(null,y);
    }

//默认参数
    var defaults={
        css3:false,
        js:false
    }

//实例化
    var move=function(elem,options){
        var mode=null;
        if(options.css3 && isSupport){
            //css3 animation
            mode=new css3(elem);
        }else if(options.js){
            //js animation
            mode=new js(elem);
        }else{
            mode=new silent(elem);
        }

        return {
            to:$.proxy(mode.to,mode),//this指向为mode
            x:$.proxy(mode.x,mode),
            y:$.proxy(mode.y,mode)
        }
    }

//注册插件
    $.fn.extend({
        move:function(opt,x,y){
            //return this能够返回对象,方便连写
            return this.each(function(){
                var ui=$(this);
                var mode=ui.data("move");
                //opt是参数对象
                var options=$.extend({},defaults,typeof opt==="object"&&opt);
                
                //单例:一个DOM元素对应一个实例,若是已经存在则不须要反复实例化
                if(!mode){
                    mode=move(ui,options);
                    ui.data("move",mode);
                }
                
                //opt是to x y
                if(typeof mode[opt]==="function"){
                    mode[opt](x,y);
                }
            });
        }
    })

})(jQuery);