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 相关文章推荐
两个select之间option的互相添加操作(jquery实现)
Nov 12 Javascript
用Juery网页选项卡实现代码
Jun 13 Javascript
jQuery EasyUI API 中文文档 - Menu菜单
Oct 03 Javascript
跨域请求之jQuery的ajax jsonp的使用解惑
Oct 09 Javascript
javascript中window.event事件用法详解
Dec 11 Javascript
禁止按回车键提交表单的方法
Jun 11 Javascript
JavaScipt选取文档元素的方法(推荐)
Aug 05 Javascript
Javascript函数中的arguments.callee用法实例分析
Sep 16 Javascript
浅析JavaScript中的平稳退化(graceful degradation)
Jul 24 Javascript
Angular CLI 安装和使用教程
Sep 13 Javascript
vue项目实战总结篇
Feb 11 Javascript
对vuex中getters计算过滤操作详解
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
php 带逗号千位符数字的处理方法
2012/01/10 PHP
Yii2.0使用阿里云OSS的SDK上传图片、下载、删除图片示例
2017/09/20 PHP
Laravel中服务提供者和门面模式的入门介绍
2017/11/06 PHP
Yii2.0建立公共方法简单示例
2019/01/29 PHP
php输出反斜杠的实例方法
2019/09/19 PHP
javascript实现的鼠标链接提示效果生成器代码
2007/06/28 Javascript
通过JS 获取Mouse Position(鼠标坐标)的代码
2009/09/21 Javascript
浅析onsubmit校验表单时利用ajax的return false无效问题
2013/07/10 Javascript
javascript获取鼠标点击元素对象(示例代码)
2013/12/20 Javascript
Jquery1.9.1源码分析系列(六)延时对象应用之jQuery.ready
2015/11/24 Javascript
微信小程序 wxapp内容组件 progress详细介绍
2016/10/31 Javascript
Angular页面间切换及传值的4种方法
2016/11/04 Javascript
浅谈Webpack打包优化技巧
2018/06/12 Javascript
jQuery判断自定义属性data-val用法示例
2019/01/07 jQuery
利用Node.js如何实现文件循环覆写
2019/04/05 Javascript
node.js事件轮询机制原理知识点
2019/12/22 Javascript
JS实现简单的表格增删
2020/01/16 Javascript
JS通用方法触发点击事件代码实例
2020/02/17 Javascript
jquery实现异步文件上传ajaxfileupload.js
2020/10/23 jQuery
Vue实现摇一摇功能(兼容ios13.3以上)
2021/01/26 Vue.js
浅谈Python中列表生成式和生成器的区别
2015/08/03 Python
python魔法方法-自定义序列详解
2016/07/21 Python
python 运用Django 开发后台接口的实例
2018/12/11 Python
numpy中三维数组中加入元素后的位置详解
2019/11/28 Python
Python如何脚本过滤文件中的注释
2020/05/27 Python
python调用百度API实现人脸识别
2020/11/17 Python
boostrap modal 闪现问题的解决方法
2020/09/01 HTML / CSS
Charles & Colvard官网:美国莫桑石品牌
2019/06/05 全球购物
意大利网上书店:LaFeltrinelli
2020/06/12 全球购物
成教自我鉴定
2013/10/27 职场文书
培训心得体会
2013/12/29 职场文书
远程教育心得体会
2014/01/03 职场文书
小学开学典礼主持词
2014/03/19 职场文书
幼儿园园长新年寄语2015
2014/12/08 职场文书
Centos环境下Postgresql 安装配置及环境变量配置技巧
2021/05/18 PostgreSQL
vue数据字典取键值项目的字典问题
2022/04/12 Vue.js