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 相关文章推荐
jquery验证表单中的单选与多选实例
Aug 18 Javascript
Jquery实现图片左右自动滚动示例
Sep 25 Javascript
JS关闭窗口与JS关闭页面的几种方法小结
Dec 17 Javascript
JavaScript异步编程Promise模式的6个特性
Apr 03 Javascript
深入理解JavaScript程序中内存泄漏
Mar 17 Javascript
深入理解JS中的substr和substring
Apr 26 Javascript
jQuery实现的checkbox级联选择下拉菜单效果示例
Dec 26 Javascript
深入理解Angularjs中的$resource服务
Dec 31 Javascript
5种JavaScript脚本加载的方式
Jan 16 Javascript
jQuery Ajax实现跨域请求
Jan 21 Javascript
Angular 2父子组件数据传递之@Input和@Output详解(下)
Jul 05 Javascript
对node通过fs模块判断文件是否是文件夹的实例讲解
Jun 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
百度地图经纬度转换到腾讯地图/Google 对应的经纬度
2015/08/28 PHP
PHP获取链表中倒数第K个节点的方法
2018/01/18 PHP
Laravel框架实现的上传图片到七牛功能详解
2019/09/06 PHP
Laravel-admin之修改操作日志的方法
2019/09/30 PHP
javascript编程起步(第六课)
2007/02/27 Javascript
体验js中splice()的强大(插入、删除或替换数组的元素)
2013/01/16 Javascript
JavaScript中使用typeof运算符需要注意的几个坑
2014/11/08 Javascript
jQuery事件绑定和委托实例
2014/11/25 Javascript
分享JavaScript与Java中MD5使用两个例子
2015/12/23 Javascript
深入浅析JavaScript中的constructor
2016/04/19 Javascript
leaflet的开发入门教程
2016/11/17 Javascript
用vue和node写的简易购物车实现
2017/04/25 Javascript
微信小程序收藏功能的实现代码
2018/06/12 Javascript
laypage.js分页插件使用方法详解
2019/07/27 Javascript
详解搭建一个vue-cli的移动端H5开发模板
2020/01/17 Javascript
element-ui中el-upload多文件一次性上传的实现
2020/12/02 Javascript
Python中Django 后台自定义表单控件
2017/03/28 Python
python实现给微信公众号发送消息的方法
2017/06/30 Python
python实现切割url得到域名、协议、主机名等各个字段的例子
2019/07/25 Python
如何利用Python开发一个简单的猜数字游戏
2019/09/22 Python
解决python gdal投影坐标系转换的问题
2020/01/17 Python
Python动态导入模块:__import__、importlib、动态导入的使用场景实例分析
2020/03/30 Python
Python实现汇率转换操作
2020/05/03 Python
python tkinter的消息框模块(messagebox,simpledialog)
2020/11/07 Python
CSS3 Notes: -webkit-box-reflect实现倒影的实例
2016/12/08 HTML / CSS
老海军美国官网:Old Navy
2016/09/05 全球购物
ProBikeKit澳大利亚:自行车套件,跑步和铁人三项装备
2016/11/30 全球购物
墨尔本复古时尚品牌:Dangerfield
2018/12/12 全球购物
工厂实习感言
2014/01/14 职场文书
房地产项目策划书
2014/02/05 职场文书
道德之星事迹材料
2014/05/03 职场文书
正科级干部考察材料
2014/05/29 职场文书
毕业论文答辩开场白和结束语
2015/05/27 职场文书
2016大学生党校学习心得体会
2016/01/06 职场文书
《酸的和甜的》教学反思
2016/02/18 职场文书
想创业成功,需要掌握这些要点
2019/12/06 职场文书