jQuery源码学习11——动画

jQuery.setAuto这个方法实在看不出来到底有啥用,而且到后面的版本就把这个方法去掉了

直接看speed方法

jQuery.extend({
    speed: function(s,o) {
        o = o || {};

        if ( o.constructor == Function )
            o = { complete: o };

        var ss = { slow: 600, fast: 200 };
        o.duration = (s && s.constructor == Number ? s : ss[s]) || 400;

        // Queueing
        o.oldComplete = o.complete;
        o.complete = function(){
            jQuery.dequeue(this, "fx");
            if ( o.oldComplete && o.oldComplete.constructor == Function )
                o.oldComplete.apply( this );
        };

        return o;
    }
});

从名字上看很容易知道这是控制速度的一个方法

从源码中看,在animate方法中通过jQuery.speed(speed,callback)调用了一次

speed方法最终会构造一个json形式的config,结构如下:

    {
        duration:400,//持续时间
        oldComplete:function(){
            ...//自定义的函数
        },
        complete:function(){
            jQuery.dequeue(this, "fx");
            if ( o.oldComplete && o.oldComplete.constructor == Function )
                o.oldComplete.apply( this );
        }
    }

调用complete时里面的this指向一定有变化,所以等分析到调用complete的时候再看

接下来的dequeue方法也一样,从字面上来看就是出队的意思

再往下的fx方法是核心

    jQuery.extend(
        fx: function( elem, options, prop ){
            var z = this;
            z.o = {...};
            z.el = elem;
            z.a = function(){...};
            z.max = function(){...};
            z.cur = function(){...};
            z.custom = function(from,to){...};
            z.show = function( p ){...};
            z.hide = function(){...};
            z.step = function(firstNum, lastNum){...};
        }
    );

实际上,jQuery.fx在源码中被用作构造方法,从animate实力方法中发现通过new jQuery.fx()来调用了

z就是new出来的对象,然后往对象上扩展了很多方法

构造方法里面的各个方法之间相互调用,因此比较复杂,我们通过一个例子来看

$("#div1").animate({"width":500},1000,function(){alert("over");});

意思就是让#div1在1s时间内宽变到500,完了之后弹出over

1、queue

调用形式为this.queue(function(){...});

    queue: function(type,fn){
        if ( !fn ) {
            fn = type;
            type = "fx";
        }

        return this.each(function(){//此处的this是jQuery对象
            if ( !this.queue )
                this.queue = {};

            if ( !this.queue[type] )
                this.queue[type] = [];
            //以上代码是给jQuery对象里面的每个DOM元素都附加queue这个属性,queue下将会按照队列的类型来存放函数
            this.queue[type].push( fn );
            //如果当前type类型的队列里面只有一个函数,就直接执行,而且这个函数内部的this更改为了each每次遍历到的DOM对象
            if ( this.queue[type].length == 1 )
                fn.apply(this);
        });
    }

2、执行传入this.queue里面的函数

    animate: function(prop,speed,callback) {
        return this.queue(function(){

            this.curAnim = prop;//this指向queue中遍历到的DOM对象,prop形如
            /*{
                "width":500,
                "opacity":50,
                "height":200
            }*/

            for ( var p in prop ) {
                var e = new jQuery.fx( this, jQuery.speed(speed,callback), p );
                if ( prop[p].constructor == Number )            //custom的两个参数分别是起始值和目标值
                    e.custom( e.cur(), prop[p] );
                else//暂时搞不太清楚什么时候走else这个分支
                    e[ prop[p] ]( prop );
            }

        });
    },

3、cur custom

        //得到elem当前prop的值
        z.cur = function(){
            var r = parseFloat( jQuery.curCSS(z.el, prop) );
            return r && r > -10000 ? r : z.max();
        };
        //在当前实例化对象上绑定startTime、now属性,now存储的是最初从哪个值开始动,startTime和now这两个属性为接下来执行的a和step做了铺垫
        z.custom = function(from,to){
            z.startTime = (new Date()).getTime();
            z.now = from;
            z.a();

            z.timer = setInterval(function(){
                z.step(from, to);
            }, 13);
        };

4、a

        z.a = function(){
            //目前很明显options里面只有complete、oldComplete、duration三个属性,没有step
            if ( options.step )
                options.step.apply( elem, [ z.now ] );
            //当改变的样式是透明度时,对于IE浏览器要做特殊处理
            if ( prop == "opacity" ) {
                if (z.now == 1) z.now = 0.9999;
                if (window.ActiveXObject)
                    y.filter = "alpha(opacity=" + z.now*100 + ")";
                else
                    y.opacity = z.now;
            } else if ( parseInt(z.now) )
                //如果运动形式不是opacity,就直接按照数字处理
                y[prop] = parseInt(z.now) + "px";

            y.display = "block";
        };

5、step

这个step方法每隔13毫秒就会调用一次

step先获取当前调用step的时间戳

再判断是否到达了目的值

如果没到目的值,递增或递减z.now的值,并再次执行z.a将递增或递减后的值赋给DOM元素

如果到达目的值了就停掉定时器,然后判断别运动的样式是否到目的值,如果全都到了就再去做一系列后续操作,执行结束的回调函数

时间: 2024-11-07 18:42:47

jQuery源码学习11——动画的相关文章

jQuery源码学习笔记:总体架构

1.1.自调用匿名函数: (function( window, undefined ) { // jquery code })(window); 这是一个自调用匿名函数,第一个括号内是一个匿名函数,第二个括号立即执行,传参是window. 1.为什么有自调用匿名函数? 通过定义匿名函数,创建了一个"私有"空间,jQuery必须保证创建的变量不能和导入它的程序发生冲突. 2.为什么传入window? 传入window使得window由全局变量变成局部变量,jQuery访问window时,

jQuery源码学习:常用正则表达式

常用的数字正则(严格匹配) 正则 含义 ^[1-9]\d*$ 匹配正整数 ^-[1-9]\d*$ 匹配负整数 ^-?[1-9]\d*$ 匹配整数 /^(([1-9]\d*)|(0+))$/; 匹配非负整数(正整数 + 0) ^-[1-9]\d*|0$ 匹配非正整数(负整数 + 0) /^(([1-9]\d*)|0)\.\d+$/ 匹配正浮点数 ^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ 匹配负浮点数 ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\

jquery源码学习

jQuery 源码学习是对js的能力提升很有帮助的一个方法,废话不说,我们来开始学习啦 我们学习的源码是jquery-2.0.3已经不支持IE6,7,8了,因为可以少学很多hack和兼容的方法. jquery-2.0.3的代码结构如下 首先最外层为一个闭包, 代码执行的最后一句为window.$ = window.jquery = jquery 让闭包中的变量暴露倒全局中. 传参传入window是为了便于压缩 传入undefined是为了undifined被修改,他是window的属性,可以被修

菜鸟的jQuery源码学习笔记(二)

jQuery对象是使用构造函数和原型模式相结合的方式创建的.现在来看看jQuery的原型对象jQuery.prototype: 1 jQuery.fn = jQuery.prototype = { 2 //成员变量和方法 3 } 这里给原型对象起了一个别名叫做jQuery.fn.要注意的是这个jQuery.fn可不是jQuery对象的属性,而是jQuery构造方法本身的属性,它是不会传给它所创建的对象的.如果你在控制台敲$().fn的话输出的结果会是undefined.接下来看看原型对象里面有些

jquery源码学习(一)core部分

这一部分是jquery的核心 jquery的构造器 jquery的核心工具函数 构造器 jQuery = function( selector, context ) { // The jQuery object is actually just the init constructor 'enhanced' // Need init if jQuery is called (just allow error to be thrown if not included) return new jQu

jquery源码学习(二)sizzle部分 【转】

一,sizzle的基本原理 sizzle是jquery选择器引擎模块的名称,早在1.3版本就独立出来,并且被许多其他的js库当做默认的选择器引擎.首先,sizzle最大的特点就是快.那么为什么sizzle当时其他引擎都快了,因为当时其他的引擎都是按照从左到右逐个匹配的方式来进行查找的,而sizzle刚好相反是从右到左找的. 举个简单的例子 “.a .b .c”来说明为什么sizzle比较快.这个例子如果按照从左到右的顺序查找,很明显需要三次遍历过程才能结束,即先在document中查找.a,然后

jquery源码学习-构造函数(2)

最近几天一直在研究jquery源码,由于水平太低看得昏头转向.本来理解的也不是很深刻,下面就用自己的想法来说下jquery是如何定义构造函数初始化的.如果有什么不对的地方,希望个位高手指出.  一般写构造函数如下 function Aaa(){} Aaa.prototype.init = function(){}; Aaa.prototype.css = function(){}; var a1 = new Aaa(); a1.init(); //初始化 a1.css(); jQuery写法如下

jquery源码学习-初始(1)

最近几天一直在研究jquery源码,由于水平太低看得昏头转向.本来理解的也不是很深刻,下面就用自己的想法来说下jquery是如何定义构造函数初始化的.如果有什么不对的地方,希望个位高手指出. 首先要了解下什么时候自执行匿名函数 ,它的用途就是 相当于创建一个命名空间,只要把自己所有的代码写在这个特殊的函数包装内,外部不能访问,除非你允许. 基本格式 (function(){ //代码 })(); (function(){ var a = 10; function $(){ alert(a); }

jQuery源码学习笔记:构造jQuery对象

3.1源码结构: (function( window, undefined ) { var jQuery = (function() { // 构建jQuery对象 var jQuery = function( selector, context ) { return new jQuery.fn.init( selector, context, rootjQuery ); } // jQuery对象原型 jQuery.fn = jQuery.prototype = { constructor: