博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
jQuery源码学习11——动画
阅读量:5108 次
发布时间:2019-06-13

本文共 4436 字,大约阅读时间需要 14 分钟。

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元素

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

 

转载于:https://www.cnblogs.com/zhaohuiziwo901/p/5007430.html

你可能感兴趣的文章
CocoaPods的安装和使用那些事(Xcode 7.2,iOS 9.2,Swift)
查看>>
Android 官方新手指导教程
查看>>
幸运转盘v1.0 【附视频】我的Android原创处女作,请支持!
查看>>
UseIIS
查看>>
为什么int型最大的数是2147483647
查看>>
数据库连接的三层架构
查看>>
集合体系
查看>>
vi命令提示:Terminal too wide
查看>>
nyoj 5 Binary String Matching(string)
查看>>
引用 移植Linux到s3c2410上
查看>>
BizTalk 2010 单机安装
查看>>
人与人之间的差距是从大学开始的
查看>>
vue 开发过程中遇到的问题
查看>>
[Swift]LeetCode341. 压平嵌套链表迭代器 | Flatten Nested List Iterator
查看>>
MySQL5.7开多实例指导
查看>>
hdu 1029 Ignatius ans the Princess IV
查看>>
JAVA学习札记
查看>>
[UOJ] #78. 二分图最大匹配
查看>>
[51nod] 1199 Money out of Thin Air #线段树+DFS序
查看>>
poj1201 查分约束系统
查看>>