jQuery1.5.1 animate方法源码阅读


Posted in Javascript onApril 05, 2011
/*7536-7646*/ 
animate: function( prop, speed, easing, callback ) { 
if ( jQuery.isEmptyObject( prop ) ) { 
return this.each( optall.complete ); 
} 
//#7864行this.options.complete.call( this.elem )使得其可以不断的连续执行动画,比如$(‘selector').animate({prop1},speed1).animate({prop2},speed2)这样的动画队列; 
return this[ optall.queue === false ? "each" : "queue" ](function() { 
// XXX 'this' does not always have a nodeName when running the 
// test suite 
var opt = jQuery.extend({}, optall), p, 
isElement = this.nodeType === 1, 
hidden = isElement && jQuery(this).is(":hidden"), 
self = this; 
//要执行动画的prop,prop一般是一个plainObj,形如{key1:value1,key2:value2}; 
for ( p in prop ) { 
//驼峰改写,有些比如magrin-top需要变成驼峰的属性即变成marginTop;见cameCase方法; 
var name = jQuery.camelCase( p ); 
//fix属性;主要是前面camelcase的属性; 
if ( p !== name ) { 
prop[ name ] = prop[ p ]; 
delete prop[ p ]; 
p = name; 
} 
//如果执行$(..).show||$(..).hide;如果这个元素本身是hidden,而动画里面又写hide,直接运行callbacks就可以了; 
if ( prop[p] === "hide" && hidden || prop[p] === "show" && !hidden ) { 
return opt.complete.call(this); 
} 
//如果prop[key]==(height||width)并且是一个dom元素;需要有些特殊的处理; 
if ( isElement && ( p === "height" || p === "width" ) ) { 
// Make sure that nothing sneaks out 
// Record all 3 overflow attributes because IE does not 
// change the overflow attribute when overflowX and 
// overflowY are set to the same value 
opt.overflow = [ this.style.overflow, this.style.overflowX, this.style.overflowY ]; // Set display property to inline-block for height/width 
// animations on inline elements that are having width/height 
// animated 
if ( jQuery.css( this, "display" ) === "inline" && 
jQuery.css( this, "float" ) === "none" ) { 
if ( !jQuery.support.inlineBlockNeedsLayout ) { 
this.style.display = "inline-block"; 
} else { 
var display = defaultDisplay(this.nodeName); 
// inline-level elements accept inline-block; 
// block-level elements need to be inline with layout 
if ( display === "inline" ) { 
this.style.display = "inline-block"; 
} else { 
this.style.display = "inline"; 
this.style.zoom = 1; 
} 
} 
} 
} 
//如果prop[key]是一个数组;只用第一个值prop[p][0]; 
if ( jQuery.isArray( prop[p] ) ) { 
// Create (if needed) and add to specialEasing 
(opt.specialEasing = opt.specialEasing || {})[p] = prop[p][1]; 
prop[p] = prop[p][0]; 
} 
} 
if ( opt.overflow != null ) { 
//如果动画元素的overflow已经被设置的情况下,把它暂时为hidden; 
this.style.overflow = "hidden"; 
} 
//当前动画键值对,其实就是prop; 
opt.curAnim = jQuery.extend({}, prop); 
//这里便是动画的核心了,对每一个prop[key]进行处理; 
jQuery.each( prop, function( name, val ) { 
//获取一个Fx对象;传入的每一个参数都被设置成为这个对象的属性;其中self是指动画元素自身;opt是前面产生的对象; 
var e = new jQuery.fx( self, opt, name ); 
//当执行show||hide操作的时候prop==fxAttrs(参见show||hide方法) 
if ( rfxtypes.test(val) ) { 
e[ val === "toggle" ? hidden ? "show" : "hide" : val ]( prop ); 
} else { 
var parts = rfxnum.exec(val), 
//start保存了初始值,它可能在style,也可能在css中,如果该值==null,undefiend,auto,0等将被设置为0; 
start = e.cur(); 
if ( parts ) { 
//end是指变化量的大小,比如:{left:-=66px},那么end=66; 
var end = parseFloat( parts[2] ), 
//单元运算符,就是px,%;如果是一些不能带单位的,比如z-index,设置为空,否则就设置为px; 
unit = parts[3] || ( jQuery.cssNumber[ name ] ? "" : "px" ); 
// We need to compute starting value 
//如果不是px,比如%,em等等; 
if ( unit !== "px" ) { 
//设置该属性值name为(end || 1) + unit,如果end=0;设置为1;开始值被设置为start = ((end || 1) / e.cur()) * start; 
jQuery.style( self, name, (end || 1) + unit); 
//这里e.cur()和前面的start = e.cur();是不一样的,因为jQuery.style( self, name, (end || 1) + unit)的执行使得start被改变;用于处理end=0的情况;因为e.cur()作为除数,不能为0; 
start = ((end || 1) / e.cur()) * start; 
jQuery.style( self, name, start + unit); 
} 
// If a +=/-= token was provided, we're doing a relative animation 
if ( parts[1] ) { 
//end相应的被设置为运算后的变量值; 
end = ((parts[1] === "-=" ? -1 : 1) * end) + start; 
} 
e.custom( start, end, unit ); 
//如果没有数字化的运算;那么没传入的只能是''; 
} else { 
e.custom( start, val, "" ); 
} 
} 
}); 
// For JS strict compliance 
return true; 
}); 
},
Javascript 相关文章推荐
详细讲解JS节点知识
Jan 31 Javascript
utf-8编码引起js输出中文乱码的解决办法
Jun 23 Javascript
JS实现的省份级联实例代码
Jun 24 Javascript
js 赋值包含单引号双引号问题的解决方法
Feb 26 Javascript
原生js编写设为首页兼容ie、火狐和谷歌
Jun 05 Javascript
js查找节点的方法小结
Jan 13 Javascript
Javascript数组操作函数总结
Feb 05 Javascript
JavaScript的Date()方法使用详解
Jun 09 Javascript
JS验证图片格式和大小并预览的简单实例
Oct 11 Javascript
node+vue实现用户注册和头像上传的实例代码
Jul 20 Javascript
微信小程序中转义字符的处理方法
Mar 28 Javascript
解决axios post 后端无法接收数据的问题
Oct 29 Javascript
jQuery的运行机制和设计理念分析
Apr 05 #Javascript
jQuery JSON的解析方式分享
Apr 05 #Javascript
jQuery 1.5 源码解读 面向中高阶JSER
Apr 05 #Javascript
基于jquery的动态创建表格的插件
Apr 05 #Javascript
基于jquery的合并table相同单元格的插件(精简版)
Apr 05 #Javascript
新鲜出炉的js tips提示效果
Apr 03 #Javascript
使用Firebug对js进行断点调试的图文方法
Apr 02 #Javascript
You might like
php 对输入信息的进行安全过滤的函数代码
2012/06/29 PHP
php上传功能集后缀名判断和随机命名(强力推荐)
2015/09/10 PHP
thinkphp3.2实现在线留言提交验证码功能
2017/07/19 PHP
基于swoole实现多人聊天室
2018/06/14 PHP
动手学习无线电
2021/03/10 无线电
javascript 操作select下拉列表框的一点小经验
2010/03/20 Javascript
js设置和获取自定义属性的方法
2016/10/20 Javascript
JS排序之选择排序详解
2017/04/08 Javascript
Node.js中的require.resolve方法使用简介
2017/04/23 Javascript
jQuery实现打开网页自动弹出遮罩层或点击弹出遮罩层功能示例
2017/10/19 jQuery
vue+vuex+axios+echarts画一个动态更新的中国地图的方法
2017/12/19 Javascript
Bootstrap Table 双击、单击行获取该行及全表内容
2018/08/31 Javascript
深入理解vue中的slot与slot-scope
2019/04/22 Javascript
[04:10]DOTA2英雄梦之声_第11期_圣堂刺客
2014/06/21 DOTA
[02:32]DOTA2亚洲邀请赛 C9战队出场宣传片
2015/02/07 DOTA
[02:44]完美大师赛主赛事淘汰赛第二日观众采访
2017/11/24 DOTA
python中关于日期时间处理的问答集锦
2013/03/08 Python
解决windows下Sublime Text 2 运行 PyQt 不显示的方法分享
2014/06/18 Python
python各类经纬度转换的实例代码
2019/08/08 Python
Python 3.8正式发布,来尝鲜这些新特性吧
2019/10/15 Python
Python3.7实现验证码登录方式代码实例
2020/02/14 Python
Python非单向递归函数如何返回全部结果
2020/12/18 Python
使用HTML5 Canvas绘制圆角矩形及相关的一些应用举例
2016/03/22 HTML / CSS
茵宝(Umbro)英国官方商店:英国足球服装生产商
2016/12/29 全球购物
美国网上书店:Barnes & Noble
2018/08/15 全球购物
工商管理应届生求职信
2013/10/07 职场文书
先进班级集体事迹材料
2014/01/30 职场文书
王老吉广告词
2014/03/20 职场文书
终止合同协议书
2014/04/17 职场文书
《山谷中的谜底》教学反思
2014/04/26 职场文书
毕业生工作求职信
2014/06/30 职场文书
乡镇综治宣传月活动总结
2014/07/02 职场文书
毕业生银行实习自我鉴定
2014/10/14 职场文书
老公保证书怎么写
2015/02/26 职场文书
2015年党风廉政建设目标责任书
2015/05/08 职场文书
Win11局域网共享权限在哪里设置? Win11高级共享的设置技巧
2022/04/05 数码科技