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和s3captche实现一个水果名字的验证
Aug 14 Javascript
JavaScript快速检测浏览器对CSS3特性的支持情况
Sep 26 Javascript
a标签的href和onclick 的事件的区别介绍
Jul 26 Javascript
JSONP获取Twitter和Facebook文章数的具体步骤
Feb 24 Javascript
JavaScript判断是否是微信浏览器
Jun 13 Javascript
一道优雅面试题分析js中fn()和return fn()的区别
Jul 05 Javascript
Vue.js教程之计算属性
Nov 11 Javascript
Bootstrap导航条鼠标悬停下拉菜单
Jan 04 Javascript
Angular5集成eventbus的示例代码
Jul 19 Javascript
vue使用rem实现 移动端屏幕适配
Sep 26 Javascript
vue input输入框关键字筛选检索列表数据展示
Oct 26 Javascript
vuex actions异步修改状态的实例详解
Nov 06 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
详解:――如何将图片储存在数据库里
2006/12/05 PHP
php多种形式发送邮件(mail qmail邮件系统 phpmailer类)
2014/01/22 PHP
php魔术变量用法实例详解
2014/11/13 PHP
PHP 将数组打乱 shuffle函数的用法及简单实例
2016/06/17 PHP
Yii框架用户登录session丢失问题解决方法
2017/01/07 PHP
PHP判断是否微信访问的方法示例
2019/03/27 PHP
对laravel的csrf 防御机制详解,及form中csrf_token()的存在介绍
2019/10/24 PHP
PHP扩展类型及安装方式解析
2020/04/27 PHP
javascript EXCEL 操作类代码
2009/07/30 Javascript
javascript制作的网页侧边弹出框思路及实现代码
2014/05/21 Javascript
使用jquery prev()方法找到同级的前一个元素
2014/07/11 Javascript
Javascript中For In语句用法实例
2015/05/14 Javascript
javascript实现判断鼠标的状态
2015/07/10 Javascript
javascript实现数组中的内容随机输出
2015/08/11 Javascript
JS实现兼容性好,带缓冲的动感网页右键菜单效果
2015/09/18 Javascript
jquery弹出遮掩层效果【附实例代码】
2016/04/28 Javascript
js图片轮播插件的封装
2017/07/21 Javascript
深入理解js A*寻路算法原理与具体实现过程
2018/12/13 Javascript
详解小程序如何避免多次点击,重复触发事件
2019/04/08 Javascript
使用 Opentype.js 生成字体子集的实例代码详解
2020/05/25 Javascript
Python绘制3d螺旋曲线图实例代码
2017/12/20 Python
Python Json序列化与反序列化的示例
2018/01/31 Python
python 实现对文件夹中的图像连续重命名方法
2018/10/25 Python
Python基于Logistic回归建模计算某银行在降低贷款拖欠率的数据示例
2019/01/23 Python
Python 词典(Dict) 加载与保存示例
2019/12/06 Python
Python selenium爬取微信公众号文章代码详解
2020/08/12 Python
Shoes For Crews法国官网:美国领先的防滑鞋设计和制造商
2018/01/01 全球购物
英国川宁茶官方网站:Twinings茶
2019/05/21 全球购物
员工自我鉴定
2013/10/09 职场文书
高中语文教学反思
2014/01/16 职场文书
节约粮食标语
2014/06/18 职场文书
党支部活动策划方案
2014/08/18 职场文书
节约用电通知
2015/04/25 职场文书
高中美术教学反思
2016/02/17 职场文书
小学科学课教学反思
2016/02/23 职场文书
在js中修改html body的样式
2021/11/11 Javascript