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 相关文章推荐
获取Javscript执行函数名称的方法
Dec 22 Javascript
javascript KeyDown、KeyPress和KeyUp事件的区别与联系
Dec 03 Javascript
in.js 一个轻量级的JavaScript颗粒化模块加载和依赖关系管理解决方案
Jul 26 Javascript
原生js拖拽(第一课 未兼容)拖拽思路
Mar 29 Javascript
基于zepto的移动端轻量级日期插件--date_picker
Mar 04 Javascript
jquery表格datatables实例解析 直接加载和延迟加载
Aug 12 Javascript
纯JS焦点图特效实例(可一个页面多用)
Dec 07 Javascript
JS实现留言板功能
Jun 17 Javascript
WebStorm ES6 语法支持设置&babel使用及自动编译(详解)
Sep 08 Javascript
微信小程序基于slider组件动态修改标签透明度的方法示例
Dec 04 Javascript
小程序实现分类页
Jul 12 Javascript
Vue如何基于vue-i18n实现多国语言兼容
Jul 17 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和AJAX创建RSS聚合器的代码
2007/03/13 PHP
php实现遍历目录并删除指定文件中指定内容
2015/01/21 PHP
PHP序列化操作方法分析
2016/09/28 PHP
PHP培训要多少钱
2017/06/06 PHP
PHP实现单文件、多个单文件、多文件上传函数的封装示例
2019/09/02 PHP
jquery 图片上传按比例预览插件集合
2011/05/28 Javascript
javascript之典型高阶函数应用介绍
2013/01/10 Javascript
JQueryEasyUI datagrid框架的进阶使用
2013/04/08 Javascript
JavaScript对象的property属性详解
2014/04/01 Javascript
判断日期是否能跨月查询的js代码
2014/07/25 Javascript
javascript中Date()函数在各浏览器中的显示效果
2015/06/18 Javascript
jQuery实现可高亮显示的二级CSS菜单效果
2015/09/01 Javascript
angularjs ocLazyLoad分步加载js文件实例
2017/01/17 Javascript
COM组件中调用JavaScript函数详解及实例
2017/02/23 Javascript
微信小程序组件 marquee实例详解
2017/06/23 Javascript
Angular中管道操作符(|)的使用方法
2017/12/15 Javascript
vue实现表单未编辑或未保存离开弹窗提示功能
2020/04/08 Javascript
在vue-cli3中使用axios获取本地json操作
2020/07/30 Javascript
Python爬虫辅助利器PyQuery模块的安装使用攻略
2016/04/24 Python
python设置值及NaN值处理方法
2018/07/03 Python
Django Admin中增加导出CSV功能过程解析
2019/09/04 Python
Python提取PDF内容的方法(文本、图像、线条等)
2019/09/25 Python
Python表达式的优先级详解
2020/02/18 Python
浅谈Python的方法解析顺序(MRO)
2020/03/05 Python
在jupyter notebook 添加 conda 环境的操作详解
2020/04/10 Python
Django bulk_create()、update()与数据库事务的效率对比分析
2020/05/15 Python
基于Python第三方插件实现西游记章节标注汉语拼音的方法
2020/05/22 Python
CSS3用@font-face实现自定义英文字体
2013/09/23 HTML / CSS
惠普新加坡官方商店:HP Singapore
2020/04/17 全球购物
如何查找和删除数据库中的重复数据
2014/11/05 面试题
酒店服务实习自我鉴定
2013/09/22 职场文书
爷爷追悼会答谢词
2014/01/24 职场文书
教育英语专业毕业生的求职信
2014/03/13 职场文书
2014年党员个人剖析材料
2014/10/08 职场文书
创先争优宣传标语
2014/10/08 职场文书
Java Kafka 消费积压监控的示例代码
2021/07/01 Java/Android