javascript的定时器-《JavaScript从入门到精通》JS运动进阶

后来我们已经掌握了很多运动相关的知识,构建了自己的运动框架。 事实上,距离真正的完成版运动车架还有很远的距离。

链条运动框架

当我们解释链条运动框架时,我们需要解释什么是弹跳函数。 在我们之前的一个运动函数startMove中,如果我们再加一个参数,并且参数是一个函数,我们要在运动结束后调用这个函数——这就是所谓的回弹函数。

function startMove(obj, attr, iTarget, fnEnd){
 clearInterval(obj.timer);
 obj.timer=setInterval(function (){
 var cur=0;
 if(attr=='opacity')
 {
 cur=Math.round(parseFloat(getStyle(obj, attr))*100);
 }
 else
 {
 cur=parseInt(getStyle(obj, attr));
 }
 var speed=(iTarget-cur)/6;
 speed=speed>0?Math.ceil(speed):Math.floor(speed);
 if(cur==iTarget)
 {
 clearInterval(obj.timer);
 if(fnEnd)fnEnd();
 }
 else
 {
 if(attr=='opacity')
 {
 obj.style.filter='alpha(opacity:'+(cur+speed)+')';
 obj.style.opacity=(cur+speed)/100;
 }
 else
 {
 obj.style[attr]=cur+speed+'px';
 }
 }
 }, 30);};

在clearInterval之后javascript的定时器,我们调用这个函数(其实我们需要判断该函数是否传入)。

 
 
 无标题文档
 
 #div1 {width:100px; height:100px; background:red; filter:alpha(opacity:30); opacity:0.3;}
 
 
 
 window.onload=function ()
 {
 var oDiv=document.getElementById('div1');
 oDiv.onmouseover=function ()
 {
 startMove(oDiv, 'width', 300, function (){
 startMove(oDiv, 'height', 300, function (){
 startMove(oDiv, 'opacity', 100);
 });
 });
 };
 oDiv.onmouseout=function ()
 {
 startMove(oDiv, 'opacity', 30, function (){
 startMove(oDiv, 'height', 100, function (){
 startMove(oDiv, 'width', 100);
 });
 });
 };
 };
 
 
 
 

疗效如下:

javascript的定时器_定时器怎么设置时间视频教程_定时器开关怎么接线

可以看到,我们通过回弹函数的嵌套,实现了炫酷的拉伸效果——这就是一个简单的链条运动框架。

完美的运动框架

到目前为止,我们所学的运动框架仍然存在问题:

 
 
 无标题文档
 
 #div1 {width:100px; height:100px; background:red;}
 
 
 
 window.onload=function ()
 {
 var oBtn=document.getElementById('btn1');
 var oDiv=document.getElementById('div1');
 oBtn.onclick=function ()
 {
 startMove(oDiv, 'width', 300);
 startMove(oDiv, 'height', 300);
 };
 };
 
 
 
 
 

疗效如下:

可以看到,我们试图同时改变div的宽度和高度,但最终只改变了高度。 原因是定时器两次调用该函数造成干扰,所以只有后面的startmove函数生效。 那么,我们目前的运动框架无法同时改变多个属性,我们应该如何解决呢? 答案是通过json。 json 的一个重要用法是循环 - 使用 forin。 以前我们通过两个参数传入属性和属性值。 现在我们直接传入一个jsonjavascript的定时器,将属性和属性值分别作为键值和通配符传入,这样就可以同时传入多组值了。

function startMove(obj, json, fnEnd){
 clearInterval(obj.timer);
 obj.timer=setInterval(function (){
 var bStop=true; //假设:所有值都已经到了
 for(var attr in json)
 {
 var cur=0;
 if(attr=='opacity')
 {
 cur=Math.round(parseFloat(getStyle(obj, attr))*100);
 }
 else
 {
 cur=parseInt(getStyle(obj, attr));
 }
 var speed=(json[attr]-cur)/6;
 speed=speed>0?Math.ceil(speed):Math.floor(speed);
 if(cur!=json[attr])
 bStop=false;
 if(attr=='opacity')
 {
 obj.style.filter='alpha(opacity:'+(cur+speed)+')';
 obj.style.opacity=(cur+speed)/100;
 }
 else
 {
 obj.style[attr]=cur+speed+'px';
 }
 }
 if(bStop)
 {
 clearInterval(obj.timer);
 if(fnEnd)fnEnd();
 }
 }, 30);}

通过json通配符对和forin循环,我们可以同时更改一个元素的多个属性。 这里注意,当属性值等于目标值时,原始运动帧就会停止,但是几个运动同时结束的时间并不相同——我们应该等到所有运动都结束后再关闭定时器,因此我们构建了一个 bStop 变量来确定所有运动是否都已到达终点。

 
 
 无标题文档
 
 #div1 {width:100px; height:100px; background:red; filter:alpha(opacity:30); opacity:0.3;}
 
 
 
 window.onload=function ()
 {
 var oBtn=document.getElementById('btn1');
 var oDiv=document.getElementById('div1');
 oBtn.onclick=function ()
 {
 startMove(oDiv, {width:101, height: 300, opacity: 100}, function (){
 alert('a');
 });
 };
 };
 
 
 
 
 

疗效如下:

这样,这个框架就可以同时改变元素的不同属性值(通过json实现),也可以分阶段改变属性值(通过bounce函数实现),从而形成一个比较完美的运动框架。 在css2的范围内,这个运动框架早就足够使用了。

至此,我们的练习框架已经基本讲清楚了。 以下是我们编制的练习框架的摘要: