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 相关文章推荐
网页里控制图片大小的相关代码
Jun 13 Javascript
jQuery 跨域访问问题解决方法
Dec 02 Javascript
JQuery教学之性能优化
May 14 Javascript
jquery+CSS3实现淘宝移动网页菜单效果
Aug 31 Javascript
jquery单击事件和双击事件冲突解决方案
Mar 02 Javascript
基于jQuery实现Tabs选项卡自定义插件
Nov 21 Javascript
js遮罩效果制作弹出注册界面效果
Jan 25 Javascript
详解使用create-react-app快速构建React开发环境
May 16 Javascript
微信小程序input框中加入小图标的实现方法
Jun 19 Javascript
微信小程序实现时间预约功能
Nov 27 Javascript
JavaScript实现轮播图特效
Apr 10 Javascript
Auto.JS实现抖音刷宝等刷视频app,自动点赞,自动滑屏,自动切换视频功能
May 08 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 压缩文件夹的类代码
2009/11/05 PHP
PHP Session变量不能传送到下一页的解决方法
2009/11/27 PHP
分享别人写的一个小型js框架
2007/08/13 Javascript
用Mootools获得操作索引的两种方法分享
2011/12/12 Javascript
对Jquery中的ajax再封装,简化操作示例
2014/02/12 Javascript
JavaScript中实现依赖注入的思路分享
2015/01/15 Javascript
js数组依据下标删除元素
2015/04/14 Javascript
JavaScript重载函数实例剖析
2016/05/13 Javascript
JS实现环形进度条(从0到100%)效果
2016/07/05 Javascript
js获取html的span标签的值方法(超简单)
2016/07/26 Javascript
JS正则验证多个邮箱完整实例【邮箱用分号隔开】
2017/04/19 Javascript
基于jQuery实现手风琴菜单、层级菜单、置顶菜单、无缝滚动效果
2017/07/20 jQuery
使用ngrok+express解决本地环境中微信接口调试问题
2018/02/26 Javascript
Vue异步组件处理路由组件加载状态的解决方案
2018/09/07 Javascript
详解如何使用koa实现socket.io官网的例子
2018/11/04 Javascript
微信小程序实现form表单本地储存数据
2019/06/27 Javascript
VUE实现强制渲染,强制更新
2019/10/29 Javascript
Json实现传值到后台代码实例
2020/06/30 Javascript
Vue js with语句原理及用法解析
2020/09/03 Javascript
vue祖孙组件之间的数据传递案例
2020/12/07 Vue.js
python使用xauth方式登录饭否网然后发消息
2014/04/11 Python
python计算N天之后日期的方法
2015/03/31 Python
Python实现批量下载图片的方法
2015/07/08 Python
关于Django外键赋值问题详解
2017/08/13 Python
python+matplotlib绘制旋转椭圆实例代码
2018/01/12 Python
Python Django 添加首页尾页上一页下一页代码实例
2019/08/21 Python
python GUI库图形界面开发之pyinstaller打包python程序为exe安装文件
2020/02/26 Python
Python代码需要缩进吗
2020/07/01 Python
Python控制鼠标键盘代码实例
2020/12/08 Python
详解CSS3中使用gradient实现渐变效果的方法
2015/08/18 HTML / CSS
印度尼西亚在线时尚购物网站:ZALORA印尼
2016/08/02 全球购物
公司委托书格式
2014/08/01 职场文书
优秀团员事迹材料1000字
2014/08/20 职场文书
党代会心得体会
2014/09/04 职场文书
股权投资协议书
2016/03/23 职场文书
java中如何截取字符串最后一位
2022/07/07 Java/Android