JavaScript 动画入门。
JavaScript 动画入门。
目录
引言
在过去的几年里,互联网发展迅速。AJAX 等方法的引入推动了网络发展,加上软件、技术和用户对网络期望的不断进步,网页设计标准被推得越来越高。
网页变得越来越用户友好和丰富,实现了流畅的过渡和柔和的图形;这些功能丰富的页面中有一个元素就是动画。许多网站通过淡入淡出或闪烁按钮,或卷起和卷下元素等过渡来实现动画。所有这些动画都可以使用 JavaScript 相当容易地创建,本文将对此进行介绍。
先决条件
为了能够理解本文并使用它,需要对 JavaScript 有一个大致的了解,但由于它只是对 JavaScript 动画的介绍,因此不会深入探讨更复杂的概念和方法。
动画对象
概念
在 JavaScript 中动画对象的概念与动画任何事物都是相同的。被动画化的对象在一定时间段内,以一定的间隔,经过一系列“步骤”进行改变。在每个步骤中,对象可以以多种方式进行改变,这种平稳的运行使得对象看起来是动画的。这种动画概念可以使用 JavaScript 相对容易地实现,如下所述。
一个基本动画
就我个人而言,我最喜欢用 JavaScript 编写的动画是淡入淡出函数,仅仅因为 L 它只改变一个属性(对象的 opacity),所以实现起来非常容易。然而,在深入代码之前,需要解释两个关键函数和样式
setTimeout(code, milliseconds)
:此函数是 JavaScript 库的一部分,在经过指定毫秒数后调用指定的code
。所有浏览器都标准支持它。obj.style.opacity
,obj.style.filter
:opacity 样式随 CSS2 引入。它在 Internet Explorer 和基于 Mozilla 的浏览器(Firefox、Safari 等)中都受支持,但实现方式不同。在 Internet Explorer 中,它以滤镜的形式实现,值为alpha(opacity=o)
,其中o
是 0-100 之间的数字,0 表示完全透明,100 表示完全不透明;在基于 Mozilla 的浏览器中,它以样式opacity
的形式实现,值为 0 到 1 之间,其中 0 表示完全透明,1 表示完全不透明。
通过淡入淡出动画,淡入淡出对象的 opacity 从起始 opacity 逐渐增加或减少到结束 opacity。此示例将演示一个淡出动画,从 100% opacity 到 0% opacity,分 10 个“步骤”
<script language="Javascript">
..
//Detect browser for later use
browser = undefined;
if(navigator.userAgent.indexOf("MSIE")!=-1)
browser = "IE";
else
browser = "Mozilla";
//Called to fade element
function fade(element)
{
//We will fade the object in 10 steps
var steps = 10;
//Set the starting opacity
setOpacity(element, 1);
//Loops the timer function
for(i=0; i<steps; ++i) {
setTimeout(function(){fadeCallback(element);}, (30*i));
}
}
//Callback to timer function
function fadeCallback(element)
{
//Get the current opacity
var opacity=getOpacity(element);
//Set the new opacity
setOpacity(element, opacity-0.1);
}
//Gets an element's opacity
function getOpacity(element)
{
var opacity = null;
//Get the opacity based on the current browser used
if(browser=="IE") {
filter = element.style.filter;
if(filter) {
alpha = filter.split("alpha(opacity=");
opacity = alpha[1].substr(0,(alpha[1].length-1))/100;
}
}
else {
opacity = element.style.opacity;
}
return opacity;
}
//Sets an element's opacity
function setOpacity(element, o)
{
//Set the opacity based on the current browser used
if(browser=="IE") {
element.style.filter = "alpha(opacity=" + (o*100) + ")";
}
else {
element.style.opacity = o;
}
}
..
</script>
然后可以通过调用 fade(element)
运行动画,其中 element
是对元素的引用,例如
<div style="width: 50px; height: 50px; background-color: red;" onClick="fade(this);">
</div>
它将在点击时淡出 DIV
。
由于这可能难以理解,我将把每个部分分解成更容易管理的小块
..
if(navigator.userAgent.indexOf("MSIE")!=-1)
browser = "IE";
else
browser = "Mozilla";
..
第一段代码只是一个简单的检测浏览器是 Internet Explorer 还是“Mozilla”(非 IE 浏览器)的方法,因为这将在后面获取或设置元素的 opacity 时使用。代码使用 navigator.userAgent
变量,该变量返回当前浏览器标识符 string
,然后检查它是否包含“MSIE”,因为这意味着当前浏览器是 Internet Explorer。如果不是,则使用哪个浏览器无关紧要,因为它们都将使用另一个标准 opacity 样式。
fade() 函数
..
function fade(element)
{
//We will fade the object in 10 steps
var steps = 10;
//Set the starting opacity
setOpacity(element, 1);
//Loops the timer function
for(i=0; i<steps; ++i) {
setTimeout(function(){fadeCallback(element);}, (30*i));
}
}
..
此函数用于淡出元素。它接受一个参数 element
,它是要淡出的元素的句柄。setTimeout()
函数也在此处使用。它在循环中调用以调用 fadeCallback()
函数,该函数将更改淡出元素的 opacity。(30*i)
作为毫秒数,以便每 30 毫秒调用一次 fadeCallback()
。element
的 opacity
设置为 1
作为起始 opacity
。另请注意,回调函数周围有 function() {
.. }
。这是因为当函数应用了参数时,如果简单地写成 fadeCallback(element)
,那么函数将立即被调用,而不是设置为计时器函数。
fadeCallback() 函数
..
function fadeCallback(element)
{
//Get the current opacity
var opacity=getOpacity(element);
//Set the new opacity
setOpacity(element, opacity-0.1);
}
..
此函数是由 setTimeout()
函数调用的回调函数。它检索正在淡出元素的当前 opacity,然后通过将当前 opacity 减少 0.1
来设置新的 opacity。
getOpacity() 函数
..
function getOpacity(element)
{
var opacity = null;
//Get the opacity based on the current browser used
if(browser=="IE") {
filter = element.style.filter;
if(filter) {
alpha = filter.split("alpha(opacity=");
opacity = alpha[1].substr(0,(alpha[1].length-1))/100;
}
}
else {
opacity = element.style.opacity;
}
return opacity;
}
..
此函数获取正在淡出元素的当前 opacity
。如前所述,Internet Explorer 和基于 Mozilla 的浏览器处理 opacity 的方式不同,因此此函数使用先前设置的 browser
变量来确定要使用的方法。然后返回 opacity 以供使用,比例介于 0
和 1
之间(其中 0
表示完全透明,1
表示完全不透明)。
setOpacity() 函数
..
function setOpacity(element, o)
{
//Set the opacity based on the current browser used
if(browser=="IE") {
element.style.filter = "alpha(opacity=" + (o*100) + ")";
}
else {
element.style.opacity = o;
}
}
..
此函数设置正在淡出元素的 opacity。与 getOpacity()
函数一样,它使用先前设置的 browser
变量来区分 Internet Explorer 和基于 Mozilla 的浏览器 opacity 处理。
如前所述,由于这只是一篇入门文章,我只介绍了如何淡出元素,但是,淡入元素的原理是相同的,只是起始 opacity 为 0
,并且在每个步骤中 opacity 都会增加。
setTimeout() 还是 setInterval()?
有什么区别?
JavaScript 中有两个关键函数可用于动画对象。第一个是已经演示过的 setTimeout()
,另一个是 setInterval()
。它们都执行类似的功能,但有一个细微的区别。它们的共同点是它们都在经过指定毫秒数后调用一个函数,但是 setTimeout()
只在时间段结束后调用此函数一次,而 setInterval()
在每经过 x 毫秒后循环调用该函数,直到调用 clearInterval()
函数为止。
那么哪个函数是最好的呢?在尝试了这两种方法之后,我发现它们都同样有用,并且都需要编写代码来检查动画是否完成;对于 setTimeout()
,fade()
函数根据步骤数计算它必须被调用的次数,而对于 setInterval()
,回调函数中的代码决定动画是否完成。为了这个简单的动画演示,setTimeout()
更合适,因为动画回调函数被调用的次数是在 fade()
函数中计算的,而使用 setInterval()
,动画是否完成是在动画回调函数中确定的,并且必须存储计时器 ID(请参阅下面的示例)。但是,我发现对于更大规模、更复杂的动画,setInterval()
函数更合适,特别是对于每步改变不透明度增量/减量等方法。
使用 setInterval() 的示例
使用 setInterval()
函数的动画示例如下
..
//Detect browser for later use
..
//Stores the setInterval() ID
timer = null;
//Called to fade element
function fade(element)
{
//Set the timer interval to 30ms and store the setInterval() ID
timer = setInterval(function(){fadeCallback(element);}, 30);
}
//Callback to timer function
function fadeCallback(element)
{
//Get the current opacity
var opacity=getOpacity(element);
//Clears the interval if at the end of the animation
if((opacity-0.1)==0)
clearInterval(timer);
//Set the new opacity
setOpacity(element, opacity-0.1);
}
//Gets an element's opacity
function getOpacity(element)
{
..
}
//Sets an element's opacity
function setOpacity(element, o)
{
..
}
..
这个例子与使用 setTimeout()
函数的例子非常相似,但有一些明显的区别。如您所见,用于确定动画是否完成的代码包含在动画回调函数中
if((opacity-0.1)==0)
clearInterval(timer);
这利用了 clearInterval()
函数,它删除使用 setInterval()
函数创建的计时器,其唯一参数是所创建计时器的 ID。如示例所示,在调用 setInterval()
函数时返回计时器 ID
timer = setInterval(function(){fadeCallback(element);}, 30);
如您所见,setInterval()
ID **必须**存储,以便在使用后可以清除计时器。
结论
阅读本文后,您应该能够
- 了解 JavaScript 计时器的工作原理
- 能够实现一个基本的对象动画器
- 理解
setTimeout()
和setInterval()
函数之间的区别
历史
- 2008 年 7 月 23 日:未经修改的第一版