jQuery的animate函数学习记录


Posted in Javascript onAugust 08, 2014

很久之前就对jQuery animate的实现非常感兴趣,不过前段时间很忙,直到前几天端午假期才有时间去研究。

jQuery.animate的每种动画过渡效果都是通过easing函数实现的。jQuery1.4.2中就预置了两个这样的函数:

easing: {
linear: function( p, n, firstNum, diff ) {
return firstNum + diff * p;
},
swing: function( p, n, firstNum, diff ) {
return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
}
}

从参数名隐约可以推测出firstNum是初始值。要是你的数学学得比较好,你可以发现linear函数是直线方程;要是你的物理学得比较好,你可以发现它是匀速运动的位移方程(我数学和物理都没学好,是别人提醒我的……)。那么diff和p就是速度和时间了。

再看看jQuery.animate的原型:

animate: function( prop, speed, easing, callback )

各参数的说明如下:

prop:一组包含作为动画属性和终值的样式属性和及其值的集合。
speed:动画时长。
easing:要使用的擦除效果的名称。
callback:动画完成时执行的函数。

元素的当前样式值(firstNum)可以获取,动画时长(p)就是duration,最终样式值是prop。理论上说,动画速度(diff)是可以算出来的。但是这又必然需要另一个函数进行运算。这样做明显是不明智的。再看看调用easing函数的相关代码(位于jQuery.fx.prototype.step中):

var t = now();
...
var n = t - this.startTime;
this.state = n / this.options.duration;
...
this.pos = jQuery.easing[specialEasing || defaultEasing](this.state, n, 0, 1, this.options.duration);

可以发现,p参数的值也就是this.state的值,从上下文得知它实际上是动画的时间进度。而firstNum和diff的参数值都是写死的,分别是0和1。这下easing函数的秘密完全被解开,p、firstNum、diff都是百分率而非实际数值,easing函数的返回值也就是位移的进度。diff的值是1,也就是以1倍的速度运行动画。算出位移进度后,通过“初始值+(最终值-初始值)×进度”就可以算出当前位移值:

this.now = this.start + ((this.end - this.start) * this.pos);

通过setInterval每隔一定时间(jQuery中是13ms)进行一次位移运算,直到当前时间与初始时间的差值大于动画时长,这就是jQuery.animate的执行过程。

按照常规思路,动画的实现方式是这样的:通过setInterval每隔一定时间给某个值增加特定数值,直到这个值达到限制值。这样做的主要问题是,不同浏览器的运行速度不同,从而导致动画速度有差异,一般是IE下比较慢,Firefox下比较快。而jQuery.animate是以当前时间来决定位移值,某个时刻的位移值总是固定的,因而动画速度不会有差异。

Javascript 相关文章推荐
js每次Title显示不同的名言
Sep 25 Javascript
优化javascript的执行效率一些方法总结
Dec 25 Javascript
关于onchange事件在IE和FF下的表现及解决方法
Mar 08 Javascript
JS模式之单例模式基本用法
Jun 30 Javascript
JavaScript入门系列之知识点总结
Mar 24 Javascript
详解vue服务端渲染(SSR)初探
Jun 19 Javascript
谈谈对vue响应式数据更新的误解
Aug 01 Javascript
解决vue同一slot在组件中渲染多次的问题
Sep 06 Javascript
详解ES6 Symbol 的用途
Oct 14 Javascript
详解create-react-app 2.0版本如何启用装饰器语法
Oct 23 Javascript
js图片无缝滚动插件使用详解
May 26 Javascript
JS sort方法基于数组对象属性值排序
Jul 10 Javascript
jQuery中get和post方法传值测试及注意事项
Aug 08 #Javascript
JSON.stringify转换JSON时日期时间不准确的解决方法
Aug 08 #Javascript
js事件监听机制(事件捕获)总结
Aug 08 #Javascript
使用jquery.qrcode生成彩色二维码实例
Aug 08 #Javascript
兼容最新firefox、chrome和IE的javascript图片预览实现代码
Aug 08 #Javascript
js调试工具console.log()方法查看js代码的执行情况
Aug 08 #Javascript
JS创建类和对象的两种不同方式
Aug 08 #Javascript
You might like
php daddslashes()和 saddslashes()有哪些区别分析
2012/10/26 PHP
php自动加载机制的深入分析
2013/06/08 PHP
学习thinkphp5.0验证类使用方法
2017/11/16 PHP
PHP递归算法的简单实例
2019/02/28 PHP
某页码显示的helper 少量调整,另附js版
2010/09/12 Javascript
javascript hashtable 修正版 下载
2010/12/30 Javascript
javascript中length属性的探索
2011/07/31 Javascript
js获取日期:昨天今天和明天、后天
2014/06/11 Javascript
AngularJS基于ngInfiniteScroll实现下拉滚动加载的方法
2016/12/14 Javascript
Bootstrap table 定制提示语的加载过程
2017/02/20 Javascript
NodeJS爬虫实例之糗事百科
2017/12/14 NodeJs
浅析java线程中断的办法
2018/07/29 Javascript
Javascript中绑定click事件的四种方式介绍
2018/10/26 Javascript
vue fetch中的.then()的正确使用方法
2020/04/17 Javascript
js实现批量删除功能
2020/08/27 Javascript
[04:48]DOTA2上海特锦赛小组赛第三日 TOP10精彩集锦
2016/02/28 DOTA
在Python3中初学者应会的一些基本的提升效率的小技巧
2015/03/31 Python
python输出指定月份日历的方法
2015/04/23 Python
python实现list由于numpy array的转换
2018/04/04 Python
使用pandas对两个dataframe进行join的实例
2018/06/08 Python
python绘制地震散点图
2019/06/18 Python
PyQt 图解Qt Designer工具的使用方法
2019/08/06 Python
python GUI库图形界面开发之PyQt5滑块条控件QSlider详细使用方法与实例
2020/02/28 Python
keras 自定义loss损失函数,sample在loss上的加权和metric详解
2020/05/23 Python
详解基于python的全局与局部序列比对的实现(DNA)
2020/10/07 Python
python实现测试工具(二)——简单的ui测试工具
2020/10/19 Python
matplotlib绘制多子图共享鼠标光标的方法示例
2021/01/08 Python
Roxy荷兰官方网站:冲浪、滑雪板、服装和配件
2019/10/22 全球购物
如何利用XMLHTTP检测URL及探测服务器信息
2013/11/10 面试题
化学实验员岗位职责
2013/12/28 职场文书
祖国在我心中演讲稿600字
2014/05/04 职场文书
小学节能减排倡议书
2014/05/15 职场文书
乡镇保密工作责任书
2014/07/28 职场文书
离婚代理词范文
2015/05/23 职场文书
员工工作失职检讨书范文!
2019/07/03 职场文书
mysql分组后合并显示一个字段的多条数据方式
2022/01/22 MySQL