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 相关文章推荐
使用javascript:将其它类型值转换成布尔类型值的解决方法详解
May 07 Javascript
Jquery.addClass始终无效原因分析
Sep 08 Javascript
js中iframe调用父页面的方法
Oct 30 Javascript
javascript中parseInt()函数的定义和用法分析
Dec 20 Javascript
JavaScript中日期函数的相关操作知识
Aug 03 Javascript
js判断出两个字符串最大子串的函数实现方法
Nov 01 Javascript
简单谈谈gulp-changed插件
Feb 21 Javascript
JS实现问卷星自动填问卷脚本并在两秒自动提交功能
Jun 17 Javascript
d3绘制基本的柱形图的实现代码
Dec 12 Javascript
vue项目中使用scss的方法步骤
May 16 Javascript
基于vue 动态菜单 刷新空白问题的解决
Aug 06 Javascript
js 将多个对象合并成一个对象 assign方法的实现
Sep 24 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
基于empty函数的输出详解
2013/06/17 PHP
PHP在弹框中获取foreach中遍历的id值并传递给地址栏
2017/06/13 PHP
PHP时间日期增减操作示例【date strtotime实现加一天、加一月等操作】
2018/12/21 PHP
laravel 如何实现引入自己的函数或类库
2019/10/15 PHP
PHP vsprintf()函数格式化字符串操作原理解析
2020/07/14 PHP
prototype1.4中文手册
2006/09/22 Javascript
json-lib出现There is a cycle in the hierarchy解决办法
2010/02/24 Javascript
jquery 的 $("#id").html() 无内容的解决方法
2010/06/07 Javascript
js控制CSS样式属性语法对照表
2012/12/11 Javascript
javascript ready和load事件的区别示例介绍
2013/08/30 Javascript
js中如何复制一个对象并获取其所有属性和属性对应的值
2013/10/24 Javascript
JS+CSS实现淡入式焦点图片幻灯切换效果的方法
2015/02/26 Javascript
javascript检查浏览器是否已经启用XX功能
2015/07/10 Javascript
prototype.js常用函数详解
2016/06/18 Javascript
ng2学习笔记之bootstrap中的component使用教程
2017/03/09 Javascript
js Array.slice的8种不同用法示例
2019/07/10 Javascript
VUE项目中加载已保存的笔记实例方法
2019/09/14 Javascript
跟老齐学Python之集成开发环境(IDE)
2014/09/12 Python
Python中的一些陷阱与技巧小结
2015/07/10 Python
python机器学习之贝叶斯分类
2018/03/26 Python
Python实现的简单计算器功能详解
2018/08/25 Python
运用Python的webbrowser实现定时打开特定网页
2019/02/21 Python
python中web框架的自定义创建
2019/09/08 Python
浅谈python输出列表元素的所有排列形式
2020/02/26 Python
python数据预处理 :样本分布不均的解决(过采样和欠采样)
2020/02/29 Python
Python使用grequests并发发送请求的示例
2020/11/05 Python
python实现按日期归档文件
2021/01/30 Python
社区国庆节活动方案
2014/02/05 职场文书
企业节能减排实施方案
2014/03/19 职场文书
奥巴马的演讲稿
2014/05/15 职场文书
护士节策划方案
2014/05/19 职场文书
2014年班主任工作总结
2014/11/08 职场文书
人与自然观后感
2015/06/16 职场文书
校园新闻稿范文
2015/07/18 职场文书
SpringBoot整合MongoDB的实现步骤
2021/06/23 MongoDB
看完这篇文章获得一些java if优化技巧
2021/07/15 Java/Android