前言:其实js动画跟CSS-DOM结合的挺紧密的,都是用js函数实现一段时间内重复设置元素的样式就造成了动画,其中涉及到大量的用DOM获取元素样式操做,因此能够先看一下CSS-DOM那篇文章,此次总结一下js中的动画,这一篇是基础知识总结,只用到了setTimeout函数,还有两个定时器函数下篇文章总结,最后要实现一个纯js轮播图Demo,好的,黑喂狗javascript
------------------ 你瞅啥? -------------------------html
首先想让一个元素移动要先设置一个元素,假设咱们如今有一标签:<p id="message">Hello World!!!</p>
,咱们能够在js代码中设置它的初始位置:position:absolute,设置它距离left和right的距离,以下代码前端
function positionMessage(){ //检测与判断 if(!document.getElementById){ return false; } if(!document.getElementById("message")){ return false; } //获取元素的标签 var elem = document.getElementById("message"); //设置元素的位置 elem.style.position = "absolute"; elem.style.left = "50px"; elem.style.top = "100px"; }
接下来咱们介绍一个延迟执行函数,setTimeout(),它接受两个参数,第一个参数时字符串,内容是将要执行的那个函数名字;第二个参数是一个数值,以毫秒为单位设定须要通过多长时间后才开始执行第一个参数里面的函数。因此有个这个函数,咱们能够写一个不断改变位置的函数moveMessage(),而后把它传递给setTimeout()函数。以下代码:java
function moveMessage(){ if(!document.getElementById){ return false; } if(!document.getElementById("message")){ return false; } var elem = document.getElementById("message"); var xpos = parseInt(elem.style.left); var ypos = parseInt(elem.style.top); if(xpos ==200&&ypos == 100){ return true; } if(xpos < 200){ xpos++; } if(xpos > 200){ xpos--; } if(ypos < 100){ ypos++; } if(ypos > 100){ ypos--; } elem.style.left = xpos + "px"; elem.style.top = ypos + "px"; movement = setTimeout("moveMessage()",10); }
1.首先获取原始的left和position值,因为涉及到不少计算,因此将字符串转换为数。
2.进行一些判断,将目标位置设置在left在200px,top不变,也就是将其向右水平移动。而后进行逻辑判断:若是到达目标位置,就返回true,函数执行完毕。
3.若是没有到达位置,则不断将数值加1,若是超过设定位置则减1.
4.最后在moveMessage()函数内部设置setTimeout()函数,即在moveMessage()函数一次执行结束后,就每隔10毫秒再次调用这个函数,即在刚开始每隔10毫秒向右移动1px,直到到达设定地点函数return true结束整个函数。函数
最后要在页面加载完成后调用这个函数,因此要用到老朋友addLoadEvent()函数,以下代码:动画
function addLoadEvent(func){ var oldonload = window.onload; if(typeof window.onoad != 'function'){ window.onload = func; }else{ window.onload = function(){ oldonload(); func(); } } }
最后在页面加载完成时执行moveMessage()函数:编码
addLoadEvent(PositionMessage);
刚才建立的moveMessage()函数中有不少信息都是硬编码在函数中,这个函数的灵活性和适用范围就小,因此将一些具体的东西抽象出来,则这个函数就更加便于复用。
如今咱们建立一个moveElement()函数,看下面代码:code
//首先为这个函数传进几个参数 //@elementID:打算移动的元素的ID //@final_x:该元素目的地距左边的位置 //@final_y:该元素目的地距上边的位置 //@interval:该元素两次移动之间的停顿时间 function moveElement(elementID,final_x,final_y,interval){ //进行检测和判断 if(!document.getElementById){ return false; } if(!document.getElementById(elementID)){ return false; } var elem = document.getElementById(elementID); //参数没有引号 var xpos =parseInt(elem.style.left); var ypos = parseInt(elem.style.top); if(xpos == final_x && ypos == final_y){ return true; } if(xpos < final_x){ xpos++; } if(xpos > final_x){ xpos--; } if(ypos < final_y){ ypos++; } if(ypos > final_y){ ypos--; } elem.style.left = xpos + "px"; elem.style.top = ypos + "px"; //因为此次moveElement()函数是带参数的,因此再次调用这个函数要写成下面一行。 //movement = setTimeout("moveElement('"+elementID+"',"+final_x+","+final_y+","+interval+")",10); //可是这么写不简洁,因此能够复制给一个变量 var repeat = "moveElement('"+elementID+"',"+final_x+","+final_y+","+interval+")"; movement = setTimeout(repeat,interval); }
直到如今我终于明白为何要作一次判断减减了,由于抽象以后,可能传入的参数会让元素向相反的方向移动,这样就写可让函数不管向哪一个方向移动均可以了。htm
抽象以后,能够在positionMessage的最后直接调用moveElement函数,以下代码:对象
function positionMessage(){ //检测与判断 if(!document.getElementById){ return false; } if(!document.getElementById("message")){ return false; } //获取元素的标签 var elem = document.getElementById("message"); //设置元素的位置 elem.style.position = "absolute"; elem.style.left = "50px"; elem.style.top = "100px"; //调用移动函数,能够随意改变值,以实现不用的动画效果 moveElement("message",200,100,10); }
//函数animation传入四个参数, //@ele:要进行动画的DOM对象 //@attr:要改变的属性 //@ from , to 属性值从哪一个值到哪一个值 var animation = function(ele, attr, from, to){ var distance = Math.abs(to - from); var stepLength = distance/100; var sign = (to - from)/distance; //表明方向 var offset = 0; //step函数是每触发的时候改变一下属性值 var step = function(){ var temOffset = offset + stepLength; if(temOffset < distance){ ele.style[attr] = from + temOffset*sign + 'px'; offset = temOffset; }else{ ele.style[attr] = to + 'px'; clearInterval(intervalID); } } ele.style[attr] = from + 'px'; //先调用定时器,每10毫秒触发一次step函数 var intervalID = setTimeout(step,10); }
以上是网易前端微专业老师给出的抽象代码,还介绍了另外两个函数,将在下一篇中介绍。
另外,完整源代码中没用这个抽象函数。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>example</title> </head> <body> <p id="message">Hello World!!!</p> <script> function positionMessage(){ if(!document.getElementById){ return false; } if(!document.getElementById("message")){ return false; } var elem = document.getElementById("message"); elem.style.position = "absolute"; elem.style.left = "50px"; elem.style.top = "100px"; moveElement("message",125,25,20); } function moveElement(elementID,final_x,final_y,interval){ if(!document.getElementById){ return false; } if(!document.getElementById(elementID)){ return false; } var elem = document.getElementById(elementID); var xpos =parseInt(elem.style.left); var ypos = parseInt(elem.style.top); if(xpos == final_x && ypos == final_y){ return true; } if(xpos < final_x){ xpos++; } if(xpos > final_x){ xpos--; } if(ypos < final_y){ ypos++; } if(ypos > final_y){ ypos--; } elem.style.left = xpos + "px"; elem.style.top = ypos + "px"; var repeat = "moveElement('"+elementID+"',"+final_x+","+final_y+","+interval+")"; movement = setTimeout(repeat,interval); } //页面加载函数 function addLoadEvent(func){ var oldonload = window.onload; if(typeof window.onload != 'function'){ window.onload = func; }else{ window.onload = function(){ oldonload(); func(); } } } //页面加载时执行这个函数 addLoadEvent(positionMessage); </script> </body> </html>