1.速度(改变值Left、right、width、height、opacity)
2.缓冲运动
3.多物体运动
4.任意值变化
5.链式运动 (如:先宽后高)
6.同时运动 (如:宽高同时运动)
创建定时器:setInterval(function(){},30)
先清空定时器,在判断条件。clearinterval();
注意避免硬编码即在函数的判断之中直接使用具体的值如10,20等,应该把这些变化的值作为参数传入函数内部,即美观也方便后来的修改。
<!DOCTYPE html> <html> <head> <title>动画</title> <meta charset="utf-8"> <style type="text/css"> body,div,span{ margin: 0; padding: 0; } #div1{ width: 200px; height: 200px; background: red; position: relative; left: -200px; top: 0; } #div1 span{ width: 20px; height: 50px; background: blue; position: absolute; left: 200px; top: 75px; } </style> <script type="text/javascript"> window.οnlοad=function() { varoDiv=document.getElementById('div1'); oDiv.οnmοuseenter=function() { startMove(0); } oDiv.οnmοuseleave=function(){ startMove(-200); } } var timer =null; function startMove(iTarget){ clearInterval(timer); varoDiv=document.getElementById('div1'); timer=setInterval(function(){ var speed=0; if(oDiv.offsetLeft>iTarget) { speed=-10; } else{ speed=10; } if(oDiv.offsetLeft == iTarget) { clearInterval(timer); } else{ oDiv.style.left=oDiv.offsetLeft+speed+'px'; } },35) } </script> </head> <body> <div id="div1" ><span id="share">分享</span></div> </body> </html>
<!-- 使用js实现透明度运动而不采用直接设置css的style.opacity属性来改变透明度,这是因为css的透明度的设置是一步到位,瞬时完成的,而使用js可以实现渐隐特效 -->
opacity是不透明度,opacity为0时表示不透明度是0也就是完全透明(效果等同于css的隐藏)
filter: alpha(opacity:30); /*IE浏览器专用,opacity属性值为0~100*/
opacity:0.3; /*所有主流浏览器都支持opacity属性。.
注意:IE8和早期版本支持另一种过滤器属性。像:filter:Alpha(opacity=50),而IE8版本之前的opacity属性值是0~1*/
【没有直接的属性可以改变透明度,需要定义一个alpha】
<!DOCTYPE html> <html> <head> <title>透明度动画</title> <meta charset="utf-8"> </head> <style type="text/css"> body,div{ margin: 0; padding: 0; } #div1{ width: 200px; height: 200px; background: red; filter: alpha{opacity:30}; opacity:0.3; } </style> <script type="text/javascript"> window.οnlοad=function() { var oDiv=document.getElementById('div1'); oDiv.οnmοuseοver=function() { startMove(100); } oDiv.οnmοuseοut=function() { startMove(30); } } var timer=null; var alpha=30; function startMove(iTarget) { varoDiv=document.getElementById('div1'); clearInterval(timer); timer=setInterval(function(){ var speed=0; if (alpha>iTarget) { speed=-10; } else{ speed=10; } if (alpha==iTarget) { clearInterval(timer); } else{ alpha+=speed; oDiv.style.filter='alpha(opacity:'+alpha+')'; oDiv.style.opacity=alpha/100; } },30) } </script> <body> <div id="div1"></div> </body> </html>
缓冲运动中:向上取整Math.ceil(),向下取整Math.floor()
由于数值设置的原因,div移动到一定px后,进行相减再除20的运算后会出现小数,比如0.75,比如这时div移动到了290,程序里写到div的left=oDiv.offsetLeft+speed+'px',那么div的left就是290.75px,此时speed速度为0.75。而浏览器是不允许出现小数的,会把0.75去掉,那么就速度为0 不动了。那么div的left就变成了290,下次执行时div的left是290,算出来速度还是0.75,浏览器又省略了小数,结果就是div停在了290px,到不了目标点300。
所以向右移动 速度为正 就将变成小数的速度 向上取整 为1
向左移动 速度为负 就将变成负小数的速度向下取整
取整原因:因为有除法,当offsetLeft值变的越来越小时,最后相除会使speed变成小数,从而offsetLeft与speed相加会有小数,又因显示器的最小像素单位是1px,所以浏览器默认向下取整(变小,即floor),将小数省略,小数省略后,最终的值会变小,从而导致程序无法进入if判断,进入死循环。
这一点可以用console.log(speed)可以验证,speed的log会一直输出,因为程序死循环了
Math.floor()向取整;
Math.ceil()向上取整;
Math.round()四舍五入;
var speed = speed>0?Math.ceil(speed):Math.floor(speed);
如果(目标值-当前值)/10 不能整除的话。运动到最后,是1~9之间的数字来除以10,结果是个小于1的小数,如果用Math.floor(speed)向下取整,那就是0,speed=0,意味着不再发生变化。也就是说,当速度大于0的时候,如果用Math.floor(speed),最后不到10个像素的时候,就不会动了。所以要用Math.ceil向上取整。同理,当速度<0时,要用Math.ceil()取整。
<!DOCTYPE html> <html> <head> <title>动画</title> <meta charset="utf-8"> <style type="text/css"> body,div,span{ margin: 0; padding: 0; } #div1{ width: 200px; height: 200px; background: red; position: relative; left: -200px; top: 0; } #div1 span{ width: 20px; height: 50px; background: blue; position: absolute; left: 200px; top: 75px; } </style> <script type="text/javascript"> window.οnlοad=function() { varoDiv=document.getElementById('div1'); oDiv.οnmοuseenter=function() { startMove(0); } oDiv.οnmοuseleave=function(){ startMove(-200); } } var timer =null; function startMove(iTarget){ clearInterval(timer); varoDiv=document.getElementById('div1'); timer=setInterval(function(){ varspeed=(iTarget-oDiv.offsetLeft)/20; speed=speed>0?Math.ceil(speed):Math.floor(speed); if(oDiv.offsetLeft == iTarget) { clearInterval(timer); } else{ oDiv.style.left=oDiv.offsetLeft+speed+'px'; } },35) } </script> </head> <body> <div id="div1" ><span id="share">分享</span></div> </body> </html>
HTML代码:
<!DOCTYPE html> <html> <head> <title>JS链式动画</title> <meta charset="utf-8"> </head> <style type="text/css"> body,ul,li{ margin: 0; padding: 0; } ul,li{ list-style: none; } ul li{ width: 200px; height: 100px; background: yellow; margin-bottom: 20px; border: 4px solid #000; filter:alpha(opacity:30); opacity: 0.3; } </style> <script src="js/move.js"></script> <script type="text/javascript"> window.οnlοad=function(){ varLi=document.getElementById('li1'); Li.οnmοuseοver=function(){ startMove(Li,'width',400,function(){ startMove(Li,'height',200,function(){ startMove(Li,'opacity',100); }); }); } Li.οnmοuseοut=function(){ startMove(Li,'opacity',30,function(){ startMove(Li,'height',100,function(){ startMove(Li,'width',200); }); }); } } </script> <body> <ul> <li d="li1"></li> </ul> </body> </html>
JS方法:
function getStyle(obj,attr){ if (obj.currentStyle) { returnobj.currentStyle[attr]; } else{ returngetComputedStyle(obj,false)[attr]; } } //var timer=null; function startMove(obj,attr,iTarget,fn){ clearInterval(obj.timer); obj.timer=setInterval(function(){ //1.取当前的值 varicur=0; if(attr=='opacity') { icur= parseFloat(getStyle(obj,attr))*100; } else{ icur =parseInt(getStyle(obj,attr)); } //2.算速度 var speed =(iTarget-icur)/8; speed=speed>0?Math.ceil(speed):Math.floor(speed); //3.检测停止 if (icur==iTarget) { clearInterval(obj.timer); if (fn) { fn(); } } else{ if (attr=='opacity') { obj.style.filter='alpha(opacity:'+(icur+speed)+')'; obj.style.opacity=(icur+speed)/100; }else{ obj.style[attr]=icur+speed+'px'; } } },30) }parseFloat() 解析一个字符串并返回一个浮点数。
parseInt() 解析一个字符串并返回一个整数。
var iNum1 =parseInt("12345red"); //返回 12345
var iNum1 =parseInt("0xA"); //返回 10
var iNum1 =parseInt("56.9"); //返回 56
var iNum1 =parseInt("red"); //返回 NaN
var fNum1 =parseFloat("12345red"); //返回 12345
var fNum2 =parseFloat("0xA"); //返回 NaN
var fNum3 =parseFloat("11.2"); //返回 11.2
var fNum4 =parseFloat("11.22.33"); //返回 11.22
var fNum5 =parseFloat("0102"); //返回 102
var fNum1 =parseFloat("red"); //返回 NaN
所有offset属性的值都会包括边框值和padding,需要用getstyle属性来实现。
obj.currentStyle[attr];//针对IE浏览器
obj.getComputerStyle(obj,false)[attr];//针对FireFox浏览器
getstyle封装属性时注意区别opacity,可以把传入属性是透明度的情况挑出来,单独进行改写,区别有正常height,width整型转换用parseInt,但是透明度要用parseFloat,最后取值是应该加上math.round()让结果四舍五入在正确范围内。赋值转换要注意兼容问题,IE是filter,其他浏览器是opacity
链式动画:一个动画执行完毕后,紧接着自动执行另一个动画。 实现:给startMove函数添加一个参数func,用于传入一个函数。
function getStyle(obj,attr){ if (obj.currentStyle) { returnobj.currentStyle[attr]; } else{ returngetComputedStyle(obj,false)[attr]; } } //var timer=null; functionstartMove(obj,attr,iTarget,fn){ clearInterval(obj.timer); obj.timer=setInterval(function(){ //1.取当前的值 varicur=0; if(attr=='opacity') { icur= parseFloat(getStyle(obj,attr))*100; } else{ icur= parseInt(getStyle(obj,attr)); } //2.算速度 var speed =(iTarget-icur)/8; speed=speed>0?Math.ceil(speed):Math.floor(speed); //3.检测停止 if (icur==iTarget) { clearInterval(obj.timer); if (fn) { fn(); } } else{ if (attr=='opacity') { obj.style.filter='alpha(opacity:'+(icur+speed)+')'; obj.style.opacity=(icur+speed)/100; }else{ obj.style[attr]=icur+speed+'px'; } } },30) }