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变量作用域使用中常见错误总结
Mar 26 Javascript
判断复选框是否被选中的两种方法
Jun 04 Javascript
javascript的push使用指南
Dec 05 Javascript
JavaScript类型系统之布尔Boolean类型详解
Jun 26 Javascript
TableSort.js表格排序插件使用方法详解
Feb 10 Javascript
利用node.js写一个爬取知乎妹纸图的小爬虫
May 03 Javascript
jQuery实现可拖动进度条实例代码
Jun 21 jQuery
vue 项目地址去掉 #的方法
Oct 20 Javascript
小程序实现订单倒计时功能
Apr 23 Javascript
Vue将页面导出为图片或者PDF
Aug 17 Javascript
Vue项目实现换肤功能的一种方案分析
Aug 28 Javascript
vue实现拖拽效果
Dec 23 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
怎样在UNIX系统下安装php3
2006/10/09 PHP
利用Memcached在php下实现session机制 替换PHP的原生session支持
2010/08/21 PHP
PHP版国家代码、缩写查询函数代码
2011/08/14 PHP
php实现获取局域网所有用户的电脑IP和主机名、及mac地址完整实例
2014/07/18 PHP
PHP+MySQL实现无极限分类栏目的方法
2015/12/23 PHP
thinkPHP框架动态配置用法实例分析
2018/06/14 PHP
可兼容IE的获取及设置cookie的jquery.cookie函数方法
2013/09/02 Javascript
window.onload和$(function(){})的区别介绍
2013/10/30 Javascript
jquery左边浮动到一定位置时显示返回顶部按钮
2014/06/05 Javascript
JS实现图片放大镜效果的方法
2015/02/27 Javascript
浅析jQuery移动开发中内联按钮和分组按钮的编写
2015/12/04 Javascript
js实现内容显示并使用json传输数据
2016/03/16 Javascript
jQuery实现的网格线绘制方法
2016/06/20 Javascript
jQuery实现简单的抽奖游戏
2017/05/05 jQuery
js字符串与Unicode编码互相转换
2017/05/17 Javascript
解析Angular 2+ 样式绑定方式
2018/01/15 Javascript
解决Jquery下拉框数据动态获取的问题
2018/01/25 jQuery
JavaScript高级函数应用之分时函数实例分析
2018/08/03 Javascript
用原生 JS 实现 innerHTML 功能实例详解
2019/04/03 Javascript
vue-cli3添加模式配置多环境变量的方法
2019/06/05 Javascript
Vue-Cli 3.0 中配置高德地图的两种方式
2019/06/19 Javascript
Javascript ParentNode和ChildNode接口原理解析
2020/03/16 Javascript
Vue使用screenfull实现全屏效果
2020/09/17 Javascript
python开发中module模块用法实例分析
2015/11/12 Python
Windows中使用wxPython和py2exe开发Python的GUI程序的实例教程
2016/07/11 Python
Python二叉树的定义及常用遍历算法分析
2017/11/24 Python
Python获取时间戳代码实例
2019/09/24 Python
Cpython解释器中的GIL全局解释器锁
2020/11/09 Python
Django前后端分离csrf token获取方式
2020/12/25 Python
移动web模拟客户端实现多方框输入密码效果【附代码】
2016/03/25 HTML / CSS
介绍下Java的输入输出流
2014/01/22 面试题
幼儿园新学期寄语
2014/01/18 职场文书
啤酒节策划方案
2014/05/28 职场文书
党支部特色活动方案
2014/08/20 职场文书
向国旗敬礼活动小结
2014/09/27 职场文书
2015婚礼主持词开场白
2015/05/28 职场文书