用js实现动画效果的主要思想是利用setInterval()函数.此函数可按照指定的周期(以毫秒计)来调用函数或表达式,并且该方法会不停地调用函数,直到clearInterval()被调用或窗口被关闭。由setInterval()返回的ID值可用作clearInterval()方法的参数。
function startMove(ele,iTarget,speed){ var timer=null; clearInterval(timer);//防止方法重复执行时,计时器的重复使用 timer=setInterval(function(){ if(ele.offsetLeft!=iTarget){ ele.style.left=ele.offsetLeft+speed+"px";} },100); }
var move=document.getElementById("move"); move.onmousemove=function(){startMove(move,500,10);}
function startOpacity(ele,iTarget,speed){ var timer=null; var alpha=30;//元素透明度的值获取较难,这里直接给出 clearInterval(timer); timer=setInterval(function(){ if(alpha!=iTarget){ alpha+=speed; ele.style.filter='alpha(opacity:'+alpha+')'; //设置IE的透明度 ele.style.opacity= alpha/100; //设置fierfox等透明度,注意透明度值是小数 } },50); }实现当鼠标在元素上移动时,使元素透明度从0.3变为1,或从30变为100
var move=document.getElementById("move"); move.onmousemove=function(){ startOpacity(move,100,10);}
function bufferMove(ele,iTarget){ var timer=null; clearInterval(timer); timer=setInterval(function(){ var speed=(iTarget-ele.offsetLeft)/200; if(speed>0){ speed=Math.ceil(speed);//避免速度值出现小数的状况,因为元素有关的像素值必须为整数 speed=Math.floor(speed); } if(ele.offsetLeft!=iTarget){ ele.style.left=ele.offsetLeft+speed+"px";} },100); }实现当鼠标在元素上移动时,元素做缓冲运动到达目标值
var move=document.getElementById("move"); move.onmousemove=function(){ bufferMove(move,500); }
var container=document.getElementById("container"); var iLi=container.getElementsByTagName("li"); for(var i=0,length=iLi.length;i<length;i++){ iLi[i].timer=null;//将计时器私有 iLi[i].onmouseover=function(){ bufferMove(this,500);//注意,这里用到了闭包的知识,this并不等于iLi[i],因为变量i即使bufferMove的活动对象,同时也是其父方法的活动对象,二者共用一个内存空间,所以如果在这里用<span style="font-family: Arial, Helvetica, sans-serif;">iLi[i],该值就相当于iLi[3]</span> } iLi[i].onmouseout=function(){ bufferMove(this,200); } } function bufferMove(ele,iTarget){ clearInterval(ele.timer); ele.timer=setInterval(function(){ var speed=(iTarget-ele.offsetWidth)/10; if(speed>0){ speed=Math.ceil(speed); }else{ speed=Math.floor(speed); } if(ele.offsetWidth!=iTarget){ ele.style.width=ele.offsetWidth+speed+"px";} },100); }
function getStyle(ele,attr){ if(ele.currentStyle){ return ele.currentStyle[attr]; }else{ return getComputedStyle(ele,false)[attr]; } } var container=document.getElementById("container"); var iLi=container.getElementsByTagName("li"); for(var i=0,length=iLi.length;i<length;i++){ iLi[i].timer=null; iLi[i].onmouseover=function(){ bufferMove(this,500); } iLi[i].onmouseout=function(){ bufferMove(this,200); } } function bufferMove(ele,iTarget){ clearInterval(ele.timer); ele.timer=setInterval(function(){ var speed=(iTarget-parseInt(getStyle(ele,"width")))/10; if(speed>0){ speed=Math.ceil(speed); }else{ speed=Math.floor(speed); } if(parseInt(getStyle(ele,"width"))!=iTarget){ ele.style.width=parseInt(getStyle(ele,"width"))+speed+"px";} },100); }
编写方法,使该方法能够对不同的元素的不同属性改变,以产生运动效果。该方法传入三个值,分别为要操作的元素、要操作的元素属性和属性的目标值,由于透明度的属性值与其他属性值不同,需要单独考虑
function bufferMove(ele,attr,iTarget){ clearInterval(ele.timer); ele.timer=setInterval(function(){ console.log(ele); //获取当前的属性值 var icur=0; if(attr=="opacity"){ icur=Math.round(parseFloat(getStyle(ele,attr))*100); }else{ icur=parseInt(getStyle(ele,attr)); } var speed=(iTarget-icur)/2; if(speed>0){ speed=Math.ceil(speed); }else{ speed=Math.floor(speed); } if(icur==iTarget){ clearInterval(ele.timer); }else{ if(attr=="opacity"){ ele.style[attr]=(icur+speed)/100; ele.style.filter="filter:alpha(opacity"+(icur+speed)+")"; console.log(getStyle(ele,"opacity")); console.log(speed); }else{ ele.style[attr]=icur+speed+"px";} }},50); }5. 多物体的链式运动
链式运动就是元素一次运动完成后,随后触发第二次运动。
for(var i=0,length=iLi.length;i<length;i++){ iLi[i].timer=null; iLi[i].icur=0; iLi[i].onmouseover=function(){ bufferMove(this,"opacity",100,function(){ bufferMove(this,"height",100); }) } iLi[i].onmouseout=function(){ bufferMove(this,"height",80,function(){ bufferMove(this,"opacity",30) }); } } function bufferMove(ele,attr,iTarget,fn){ clearInterval(ele.timer); ele.timer=setInterval(function(){ //获取当前的属性值 if(attr=="opacity"){ ele.icur=Math.round(parseFloat(getStyle(ele,attr))*100); }else{ ele.icur=parseInt(getStyle(ele,attr)); } var speed=(iTarget-ele.icur)/2; if(speed>0){ speed=Math.ceil(speed); }else{ speed=Math.floor(speed); } if(ele.icur==iTarget){ clearInterval(ele.timer); //传入返回的ele元素,实现函数的回调 if(fn){fn.call(ele);} }else{ if(attr=="opacity"){ ele.style[attr]=(ele.icur+speed)/100; ele.style.filter="filter:alpha(opacity"+(ele.icur+speed)+")"; }else{ ele.style[attr]=ele.icur+speed+"px";} }},50); return ele; }6 多物体同时运动
<span style="font-size:12px;font-weight: normal;">var container=document.getElementById("container"); var iLi=container.getElementsByTagName("li"); for(var i=0,length=iLi.length;i<length;i++){ iLi[i].timer=null; iLi[i].onmouseover=function(){ bufferMove(this,{opacity:100,height:81}); } iLi[i].onmouseout=function(){ bufferMove(this,{height:80,opacity:30}); } } function bufferMove(ele,json,fn){ var flag=true; clearInterval(ele.timer); ele.timer=setInterval(function(){ //获取当前的属性值 for(var attr in json){ if(attr=="opacity"){ ele.icur=Math.round(parseFloat(getStyle(ele,attr))*100); }else{ ele.icur=parseInt(getStyle(ele,attr)); } var speed=(json[attr]-ele.icur)/2; if(speed>0){ speed=Math.ceil(speed); }else{ speed=Math.floor(speed); } if(ele.icur!=json[attr]){ flag=false; } if(attr=="opacity"){ ele.style[attr]=(ele.icur+speed)/100; ele.style.filter="filter:alpha(opacity"+(ele.icur+speed)+")"; }else{ ele.style[attr]=ele.icur+speed+"px"; } if (flag) { clearInterval(ele.timer); //回调函数 if(fn){fn.call(ele);} } }},50); return ele; }</span>