手机版

jQuery 1.9.1源代码分析系列(XV)的动画处理

时间:2021-09-21 来源:互联网 编辑:宝哥软件园 浏览:

首先,你需要具备排队的基本知识。参见前一章。

教程:jQuery下的动画处理总结://www . JB 51 . net/article/42000 . htm。

JQuery 1.9.1源代码分析系列(XV)动画处理的慢速动画核心Tween://www . JB 51 . net/article/75821 . htm

A.动画入口jquery.fn .动画函数执行流程详解。

-

根据参数,调用jQuery.speed获取动画相关参数,得到类似如下的对象;并生成动画执行函数doAnimation。

optal={ complete : fn coction()}.},//动画执行的回调时长为3360 400,//动画执行时间为easing: ' swing ',//动画效果队列: 'fx ',//动画队列old : false/fn action(){ 0.},} var empty=jquery . isempty object(prop),optoll=jquery.speed (speed,each,callback),DoAnimation=function() {//对功能的副本进行操作,确保每个功能的效果不会丢失。Varanim=动画(这个,jquery。extend ({},prop),Optall);doanimation . finish=function(){ anim . stop(true);};//空动画或完成需要立即解决如果(空| | jquery。_ data(这个,‘finish’){ anim。停止(真);} };doAnimation . finish=doAnimation;如果没有动画正在执行,立即执行动画;否则,将动画按入动画队列并等待执行。

//如果没有动画,立即执行动画;否则,将动画按入动画队列并等待执行。返回空| | Optall.queue===false?this . each(doAnimation): this . queue(optall . queue,doAnimation);可以看出,真正执行动画的地方是动画(this,jquery.extend ({},prop),optoll)函数。

B.详细讲解jquery内部函数Animation。

-

动画(elem,属性,选项)。属性是要动画化的css功能,选项是动画相关选项{complete: function () {…},duration : 400,easy 3360 undefined,old : false,queue :' FX'}。

首先,初始化一个延迟对象,用于处理动画队列。

延迟=jQuery。延期()。始终(function() { //不匹配:动画选择器中的elem删除tick.elem}),然后生成将在每个时间点执行的函数tick(两个相邻时间点之间的事件间隔默认为13毫秒)。这个tick函数会保存在jQuery.timers中,然后每次执行jQuery.fx.tick的时候都会取出来执行。

tick=function(){ if(stopped){ return false;} var current time=fxNow | | createFxNow(),剩余=Math.max(0,animation . start time animation . duration-current time),//过时的崩溃bug不允许我们使用1 - (0.5 || 0 ) (#12497) temp=剩余/animation.duration || 0,percent=1 - temp,index=0,length=animation . tweens . length;//执行()的动画效果;索引长度;index ) { animation.tweens[ index ]。运行(百分比);}//延迟生成进度报告。通知方式(elem,[动画,百分比,剩余]);if(长度百分比1){返回剩余部分;} else {//动画完成后,执行延迟队列中所有延迟的功能(包括清除动画相关数据)。解析为(elem,[动画]);返回false}}我们看到jQuery对动画进度的处理:

剩余=math.max (0,animation . starttimeanimation . duration-current time)temp=剩余/animation.duration | | 0,百分比=1-temp,进度百分比=1-剩余时间百分比。

这就是我们通常处理:的方式。假设动画在13毫秒内执行一次。目前是第n次执行,动画总时长为t. so

进度=(n*13)/T

实际上这种算法得到的时间n*13是不准确的,因为中央处理器不只是你一个程序在执行,时间片分给你的时候往往都比n*13大。而且是一个很不准确的值,导致动画感觉时快时慢,不连贯。而jQuery这种方式保证当前的事件点上动画执行结果的准确性,毕竟事件是最新计算结果。

第三,生成动画用的所有特征组成的对象动画(这个对象结构如源码所示),动画。道具中保存的是用户传入的特征(动画最终目标)。

动画=已交付。promise({ elem : elem,prop : jQuery。extend({ },properties),opts 3360 jQuery。extend(true,{ specialEasing: {,options),original properties : properties,originalOptions: options,start time : fxNow | | createFxNow(),duration: options.duration,tweens :[],createTween: function(prop,endTween(elem,animation.opts),prop,end,animation。选择。特殊租赁[道具]| |动画。选择。宽松);动画。十二岁。push(tween);返回补间;},stop:函数(gotoEnd ) { var index=0,//如果我们要进行到底,我们要运行所有的补间//否则我们跳过这个部分长度=gotoEnd?动画。十二岁。长度: 0;if(stop){返回此;} stop=true for(;索引长度;index ) { animation.tweens[ index ].运行(1);} //当我们播放最后一帧时解析//否则,拒绝if(GoToend){已交付。resolvewith(elem,[动画,GoToEnd]);} else {已送达。rejectwith(elem,[动画,GoToEnd]);}退回这个;}}) 第四,调用propFilter修正钢性铸铁特征名称以便能被浏览器识别,其中需要注意的是边框宽度/填充/边距指的不是一个钢性铸铁特征,而是四个(上下左右)

//经过propFilter,动画。选择。专门化添加了相应的特征propFilter(道具、动画。选择。特殊租赁);举例说明propFilter修正成果。

例1、css特征{ height: 200 }的修正后结果为:

道具={身高: 200 }动画。选择。特殊租赁={ height : undefined }例2:css特征{margin:200}的修正结果为:

道具={余量底部: 200,余量底部: 200,余量顶部: 200,余量底部: 200 }动画。选择。专业化={ 0余量底部:未定义,余量底部:未定义,余量底部:未定义,余量底部:未定义}第五,调用默认预过滤器做适配处理:比如对高度/宽度的动画要求显示和泛滥为特定的值才能有效果;比如对显示/隐藏动画需要对一大堆钢性铸铁特征值进行动画,并且在函数里就调用创建十二个生成缓动动画。

//animationprefiles[0]=defaultprefilfor(;索引长度;index){ result=animationprefiles[index].呼叫(动画、elem、道具、动画。opts);if(结果){ 0返回结果;}} 其中动画预过滤器[索引]值得函数就是默认预过滤器函数处理有几个比较重要的地方

默认预过滤器重点1:内联元素中高度/宽度相关动画需要设置显示特征值为内嵌块

//高度/宽度溢出passif(elem。nodetype===1('高度'在小道具中||“宽度”在小道具中)){ //确保没有什么偷偷出来//记录3个泛滥相关特征,因为工业管理学(工业工程)不能改变泛滥特征值, //当overflowX和飞越设置了相同的值opts.overflow=[ style.overflow,style.overflowX,style。溢出y];//内联元素中高度/宽度相关动画需要设置显示特征值为inline-block if (jQuery.css(elem,' display ')==' inline ' jquery。CSS(elem,' float ')==' none '){//内联元素接受内嵌块;//块级元素必须内嵌在布局上if(!jquery。支持。inlinblockneedslayout | | CSS _ default display(elem。nodename)==' inline '){ style。display=' inline-block ';} else { style。zoom=1;} } } defaultPrefilter重点2:对于高度/宽度动画泛滥都要设置为'隐藏,动画完成后恢复。这个有利于提高渲染速度。

//对于高度/宽度动画泛滥都要设置为'隐藏,动画完成后恢复if(opts。溢出){ style。溢出='隐藏';//收缩包装块if(!jquery。支持。shrinkwrapblocks){ anim。始终(function(){ style。溢出=opts。溢出[0];风格。溢出x=opts。溢出[1];风格。溢出y=opts。溢出[2];});} } defaultPrefilter重点3:显示/隐藏动画的特殊处理:显示/隐藏动画调用genFx得到形如

道具={ height : ' hide '边距底部: ' hide '边距左侧: ' hide '边距灯: ' hide ' opa city 3360 ' hide '填充底部: ' hide '填充左侧: ' hide '填充右侧: ' hide '填充p: ' hide '宽度: ' hide ' }需要进行动画处理的特征压入有把手的列表,并将相应的特征删除,后面会生成相应的缓动动画。

用于(道具中的索引){ value=道具[索引];//rfxtypes=/^(?日志|显示|隐藏)$/.可以看到最终只有和显示/隐藏的动画才会被饶茹有把手的中if(rfx类型。exec(value)){删除道具[索引];toggle=toggle | | value===' toggle ';//如果当前节点的状态和指定的状态相同则不需要处理直接进行下一个状态判断if(值===(隐藏?隐藏' : '显示'){ 0继续;}已处理。推送(索引);}}//有需要执行的动画处理则进入分支,里面会对各个特征动画生成缓动动画长度=handled . length if(length){ dataShow=jQuery ._data(elem,' fxshow' ) || jQuery ._data(elem,' fxshow ',{ });if('隐藏'在数据显示中){ hidden=DataShaw . hidden }//切换需要保存状态-启用。停止()。如果(切换){ dataShow.hidden=!隐藏的;}如果(隐藏){ jQuery(elem).show();} else { anim。done(function(){ jQuery(elem))。hide();});}动漫。done(function(){ var prop;jQuery ._removeData(elem,' fxshow ');for(prop in orig){ jquery。风格(elem,prop,orig[prop]);} });用于(索引=0;索引长度;index){ prop=handled[index];//生成缓动动画tween=anim.createTween(道具,隐藏?dataShow[prop]: 0);orig[prop]=DataShow[prop]| | jquery。风格(elem,prop);if(!(数据显示中的道具){数据显示[道具]=补间。开始;如果(隐藏){吐温。end=吐温。开始;吐温。start=prop==' width ' | | prop==' height '?1 : 0;} } }} 第六,生成缓动动画,显示/隐藏在默认预过滤器函数里面已经处理(上面的源码)。

createTweens(动画、道具);我们来看一看创建十二个中具体做了什么,先看一下创建十二个之前的动画对象

然后看一下经过创建十二个之后的动画对象的十二岁数组变成了

将边缘分解成了四个属性(边距顶部/右侧/底部/左侧)并且每个属性都有自己的动画特征。

第七,启动动画计时,定时执行滴答声

//开始动画计时jquery . FX . timer(jquery . extend(tick,{elem:elem,anim3360animation,queue 3360 animation . opts . queue });最后,将传入的动画结束回调添加到延迟队列中。

//从options中获取回调函数,并将其添加到延迟队列中。返回animation.progress(动画. opts.progress)。完成(动画. opts.done,动画. opts.complete)。失败(animation.opts.fail)。始终(动画. opts .始终)。动画功能流程到此结束。

展开:

上面提到的genFx功能是专门用来获取切换、隐藏、显示时需要动画的相关特征的。

结果属性={高度: '显示',页边距顶部: '显示',页边距右侧: '显示'。//当includeWidth为false时,没有marginBottom:“显示”。MarginLeft: 'show ',//当include with为false时,没有opacity: ' show ',width3360' show'}函数genfx (type,include with){ var,attrs={height : type},I=0;//如果包含宽度,步长值为1以完成所有的cssExpand值。//如果不包括宽度,步长值为2。跳过左/右值。//CSS expand=['top ',' right ',' bottom ',' left ']include width=include width?1 : 0;for(;i4;i=2 - includeWidth ) {哪一个=CSS expand[I];attrs[' margin ' what]=attrs[' padding ' what]=type;} if(includeWidth){ attrs . opacity=attrs . width=type;}返回attrs}动画功能比较复杂,童鞋可以用例子随意跟踪代码。这是理解jQuery源代码的好方法。推荐两个例子:

首先,有一个隐藏/显示:$('#id ')的例子。隐藏(1000);

第二,其他例子:$ ('# id ')。动画({ '左边距' :500},1000);

这是jQuery 1.9.1源代码分析系列(XV)中动画处理的全部内容。如果你有任何问题,请给我留言。谢谢你。

版权声明:jQuery 1.9.1源代码分析系列(XV)的动画处理是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。