原生js動畫效果(源碼解析)

在作頁面中,多數狀況下都會遇到頁面上作動畫效果,咱們大部分作動畫的時候都是使用框架來作(好比jquery),這裏我介紹下如何讓經過原生的js來實現像框架同樣的動畫效果!javascript

一、勻速動畫效果css

說明:勻速動畫就是動畫的效果從開始到結束每次執行的速度都是一致的html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>勻速動畫</title>
<style type="text/css">
   html,body{margin:0;padding:0;}
   div{margin:0;padding:0;}
  .odiv{width:200px; height:200px; background:#f00; position:relative; left:-200px; top:100px;}
  .sdiv{width:20px; height:60px; background:#00f; position:absolute; top:70px; right:-20px;}
</style>
</head>
<body>
<div id="odiv" class="odiv">
    <div id="sdiv" class="sdiv">
    </div>
</div>
</body>
</html>
<script language="javascript">
window.onload = function(){
    var odiv = document.getElementById('odiv');
    odiv.onmouseover = function(){
       startMover(0);
    }
    odiv.onmouseout = function(){
       startMover(-200);
    }
}
var timer = null;
function startMover(itarget){//目標值
    clearInterval(timer);//執行當前動畫同時清除以前的動畫
    var odiv = document.getElementById('odiv');
    timer = setInterval(function(){
    var speed = 0;
    if(odiv.offsetLeft > itarget){
       speed = -1;
    }
    else{
       speed = 1;
    }
    if(odiv.offsetLeft == itarget){
       clearInterval(timer);
    }
    else{
        odiv.style.left = odiv.offsetLeft+speed+'px';
        }
    },30);
}
//註明:offsetWidth = width+padding+border
//offsetHeight = height+padding+border
//offsetWidth=(border-width)*2+(padding-left)+(width)+(padding-right)
//offsetHeight=(border-width)*2+(padding-top)+(height)+(padding-bottom)
/*
offsetLeft=(offsetParent的padding-left)+(中間元素的offsetWidth)+(當前元素的margin-left)。
offsetTop=(offsetParent的padding-top)+(中間元素的offsetHeight)+(當前元素的margin-top)。
當offsetParent爲body時狀況比較特殊:
在IE8/9/10及Chrome中,offsetLeft = (body的margin-left)+(body的border-width)+(body的padding-left)+(當前元素的margin-left)。
在FireFox中,offsetLeft = (body的margin-left)+(body的padding-left)+(當前元素的margin-left)。
offsetParent屬性返回一個對象的引用,這個對象是距離調用offsetParent的元素最近的(在包含層次中最靠近的),而且是已進行過CSS定位的容器元素。 若是這個容器元素未進行CSS定位, 則offsetParent屬性的取值爲根元素的引用。
總的來講兩條規則:
一、若是當前元素的父級元素沒有進行CSS定位(position爲absolute或relative),offsetParent爲body。
二、若是當前元素的父級元素中有CSS定位(position爲absolute或relative),offsetParent取最近的那個父級元素。
*/
</script>

 二、緩衝動畫java

說明:緩衝動畫就是動畫到結束或這開始的時候,速度是隨着動畫執行的進度動態變化的jquery

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>緩衝動畫</title>
<style type="text/css">
   html,body{margin:0;padding:0;}
   div{margin:0;padding:0;}
  .odiv{width:200px; height:200px; background:#f00; position:relative; left:-200px; top:100px;}
  .sdiv{width:20px; height:60px; background:#00f; position:absolute; top:70px; right:-20px;}
</style>
</head>
<body>
<div id="odiv" class="odiv">
    <div id="sdiv" class="sdiv">
    </div>
</div>
</body>
</html>
<script language="javascript">
window.onload = function(){
    var odiv = document.getElementById('odiv');
    odiv.onmouseover = function(){
       startMover(0);
    }
    odiv.onmouseout = function(){
       startMover(-200);
    }
}
var timer = null;
function startMover(itarget){//速度和目標值
    clearInterval(timer);//執行當前動畫同時清除以前的動畫
    var odiv = document.getElementById('odiv');
    timer = setInterval(function(){
    var speed = (itarget-odiv.offsetLeft)/10;//緩衝動畫的速度參數變化值
    //若是速度是大於0,說明是向右走,那麼就向上取整
    speed = speed>0?Math.ceil(speed):Math.floor(speed);
    //Math.floor();向下取整
    if(odiv.offsetLeft == itarget){
       clearInterval(timer);
    }
    else{
        //clientLeft 返回對象的offsetLeft屬性值和到當前窗口左邊的真實值之間的距離 
        odiv.style.left = odiv.offsetLeft+speed+'px';
        }
    },30);
}
</script>

三、透明度動畫chrome

說明:處理元素透明效果的動畫json

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>透明度動畫</title>
<style type="text/css">
   html,body{margin:0;padding:0;}
   div{margin:0;padding:0;}
  .odiv{width:200px; height:200px; background:#f00; position:relative; left:0px; top:100px;opacity:0.3; filter:alpha(opacity:30); float:left; margin:10px;}
</style>
</head>
<body>
<div id="odiv" class="odiv"></div>
</body>
</html>
<script language="javascript">
window.onload = function(){
    var odiv = document.getElementsByTagName('div');
    for(var i=0;i<odiv.length;i++)
    {
          odiv[i].onmouseover = function(){
           startOP(this,100);
        }
        odiv[i].onmouseout = function(){
           startOP(this,30);
        }
        odiv[i].timer = null;//事先定義
        odiv[i].alpha = null;//事先定義
        //這裏發現一個問題,對象的動畫屬性能夠不定義,可是透明度屬性必須定義,不然報錯
    }
}
function startOP(obj,utarget){
     clearInterval(obj.timer);//先關閉定時器
     obj.timer = setInterval(function(){
     var speed = 0;
     if(obj.alpha>utarget){
        speed = -10;
     }
     else{
        speed = 10;
     }
     obj.alpha = obj.alpha+speed;
     if(obj.alpha == utarget){
        clearInterval(obj.timer);
     }
     obj.style.filter = 'alpha(opacity:'+obj.alpha+')';//基於IE的
     obj.style.opacity = parseInt(obj.alpha)/100;
     },30); 
}
</script>

四、多物體動畫瀏覽器

說明:多個物體在一塊兒執行的動畫效果
框架

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>多物體動畫</title>
<style type="text/css">
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,tr,td {margin:0;padding:0; font-size:12px;} 
table {border-collapse:collapse;border-spacing:0;} 
fieldset,img {border:0} 
address,caption,cite,code,dfn,em,strong,th,var {font-style:normal;font-weight:normal} 
ol,ul {list-style:none} 
caption,th,td{text-align:center} 
h1,h2,h3,h4,h5,h6 {font-size:100%;font-weight:normal} 
q:before,q:after {content:''} 
abbr,acronym { border:0}
.odiv{position:relative;}
.odiv ul li{width:200px; height:100px; background:yellow; margin-bottom:20px;}
</style>
</head>
<body>
<div id="odiv" class="odiv">
    <ul>
        <li></li>
        <li></li>
        <li></li>
    </ul>
</div>
</body>
</html>
<script language="javascript">
window.onload = function(){
    var olist = document.getElementsByTagName('li');
    for(var i=0; i<olist.length;i++)
    {
      olist[i].onmouseover = function(){
        startmov(this,400);
      };
      olist[i].onmouseleave = function(){
        startmov(this,200);
      };
      olist[i].timer = null;
    }
    function startmov(obj,itarget){
       clearInterval(obj.timer);//執行動畫以前清除動畫
       obj.timer = setInterval(function(){
          var speed =0;
          speed = (itarget - obj.offsetWidth)/8;
          speed = speed>0?Math.ceil(speed):Math.floor(speed);
          if(obj.offsetWidth == itarget){
           clearInterval(obj.timer);
          }
          else{
          obj.style.width = obj.offsetWidth+speed+'px';
          }
       },30);
    }
}
//offsetWidth獲取的是元素實際的寬度(包括邊框和內邊距)
//只要是多物體運動,全部的屬性都不能共用
</script>
View Code

五、獲取樣式動畫ide

說明:這裏的獲取樣式是經過計算出來元素的樣式,而後經過這個計算出來的結果來操做元素

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>樣式動畫</title>
<style type="text/css">
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,tr,td {margin:0;padding:0; font-size:12px;} 
table {border-collapse:collapse;border-spacing:0;} 
fieldset,img {border:0} 
address,caption,cite,code,dfn,em,strong,th,var {font-style:normal;font-weight:normal} 
ol,ul {list-style:none} 
caption,th,td{text-align:center} 
h1,h2,h3,h4,h5,h6 {font-size:100%;font-weight:normal} 
q:before,q:after {content:''} 
abbr,acronym { border:0}
.odiv{position:relative;width:200px; height:200px; border:2px solid #000; background:red; font-size:20px;}
</style>
</head>

<body>
<div id="odiv" class="odiv">
  hjshfjdfsdfhsdj
</div>
</body>
</html>
<script language="javascript">
/*
currentStyle:獲取計算後的樣式,也叫當前樣式、最終樣式。
優勢:能夠獲取元素的最終樣式,包括瀏覽器的默認值,而不像style只能獲取行間樣式,因此更經常使用到。
注意:不能獲取複合樣式如background屬性值,只能獲取單同樣式如background-color等。
alert (oAbc.currentStyle);
很是遺憾的是,這個好使的東西也不能被各大瀏覽器完美地支持。準確地說,在我測試的瀏覽器中,IE8和Opera 11彈出了「object CSSStyleDeclaration」;FF 十二、chrome 1四、safari 5則彈出「undefined」。
雖然currentStyle沒法適用於全部瀏覽器,可是能夠根據以上測試的結果來區分開支持、不支持的瀏覽器,而後再找到兼容的寫法。
var oAbc = document.getElementById("abc");
if(oAbc.currentStyle) {
        //IE、Opera
        alert("我支持currentStyle");
} else {
        //FF、chrome、safari
        alert("我不支持currentStyle");
}
其實在FF瀏覽器中咱們可使用getComputedStyle(obj,false)來達到與IE下currentStyle相同的效果。
getComputedStyle(obj,false):在FF新版本中只須要第一個參數,即操做對象,第二個參數寫「false」也是你們通用的寫法,目的是爲了兼容老版本的火狐瀏覽器。
兼容寫法:
var oAbc = document.getElementById("abc");
if(oAbc.currentStyle) {
        //IE、Opera
        //alert("我支持currentStyle");
        alert(oAbc.currentStyle.width);
} else {
        //FF、chrome、safari
        //alert("我不支持currentStyle");
        alert(getComputedStyle(oAbc,false).width);
}
一個空白頁面中body的id=」abc」,測試以上代碼,IE和Opera彈出「auto」,其它三款瀏覽器則彈出「***px」。雖然結果不一樣,可是能夠發現chrome和safari也都和火狐同樣,順利地讀取到了屬性值。不支持currentStyle的三款瀏覽器(FF、chrome、safari),都是支持getComputedStyle的。
結果代表:對瀏覽器是否支持currentStyle的判斷 + getComputedStyle,就能夠作到兼容各主流瀏覽器的效果。並且兼容寫法並不複雜,你掌握了嗎?^_^
支持currentStyle:IE、Opera
支持getComputedStyle:FireFox、Chrome、Safari
注意最後的彈出內容,currentStyle返回瀏覽器的默認值」auto」,而getComputedStyle則返回具體的值」**px」。這應該是二者的一個小差別,有興趣的童鞋能夠一塊兒交流研究下。
*/
window.onload = function(){
    var odiv = document.getElementById('odiv');
    odiv.onmouseover = function(){
       startMov(this);
    };
    function startMov(obj){
       setInterval(function(){
        obj.style.width = parseInt(getStyle(obj,'width'))+1+'px';
        obj.style.fontSize = parseInt(getStyle(obj,'fontSize'))+1+'px';
       },30);
    }
    function getStyle(obj,attr)
    {
      if(obj.currentStyle){
        return obj.currentStyle[attr];
      }
      else{
        return getComputedStyle(obj,false)[attr];
      }
    }
}
//offsetWidth獲取的是元素實際的寬度(包括邊框和內邊距)
//只要是多物體運動,全部的屬性都不能共用
</script>
View Code

 六、多物體複雜動畫

說明:多物體複雜動畫能夠控制元素的不一樣屬性變化來實現動畫效果

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>多物體複雜動畫</title>
<style type="text/css">
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,tr,td {margin:0;padding:0; font-size:12px;} 
table {border-collapse:collapse;border-spacing:0;} 
fieldset,img {border:0} 
address,caption,cite,code,dfn,em,strong,th,var {font-style:normal;font-weight:normal} 
ol,ul {list-style:none} 
caption,th,td{text-align:center} 
h1,h2,h3,h4,h5,h6 {font-size:100%;font-weight:normal} 
q:before,q:after {content:''} 
abbr,acronym { border:0}
.odiv{position:relative;}
.odiv ul li{width:200px; height:100px; background:yellow; margin-bottom:20px; border:2px solid #000;}
</style>
</head>
<body>
<div id="odiv" class="odiv">
    <ul>
        <li id="li1"></li>
        <li id="li2"></li>
    </ul>
</div>
</body>
</html>
<script language="javascript">
window.onload = function(){
    var li1 = document.getElementById('li1');
    var li2 = document.getElementById('li2');
    li1.onmouseover = function(){
       startMov(this,400,'width');
    };
    li1.onmouseout = function(){
       startMov(this,200,'width');
    };
    li2.onmouseover = function(){
       startMov(this,200,'height');
    };
    li2.onmouseout = function(){
       startMov(this,100,'height');
    };
    function startMov(obj,itarget,attr){
       clearInterval(obj.timer);//執行動畫以前清除動畫
       obj.timer = setInterval(function(){
          var icur = parseInt(getStyle(obj,attr));
          var speed =0;
          speed = (itarget - icur)/8;
          speed = speed>0?Math.ceil(speed):Math.floor(speed);
          if(icur == itarget){
           clearInterval(obj.timer);
          }
          else{
          obj.style[attr] = icur+speed+'px';
          }
       },30);
    }
    function getStyle(obj,attr)
    {
      if(obj.currentStyle){
        return obj.currentStyle[attr];
      }
      else{
        return getComputedStyle(obj,false)[attr];
      }
    }
}
//offsetWidth獲取的是元素實際的寬度(包括邊框和內邊距)
//只要是多物體運動,全部的屬性都不能共用
</script>
View Code

七、多物體複雜動畫(帶透明度的)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>多物體複雜動畫(帶透明度的)</title>
<style type="text/css">
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,tr,td {margin:0;padding:0; font-size:12px;} 
table {border-collapse:collapse;border-spacing:0;} 
fieldset,img {border:0} 
address,caption,cite,code,dfn,em,strong,th,var {font-style:normal;font-weight:normal} 
ol,ul {list-style:none} 
caption,th,td{text-align:center} 
h1,h2,h3,h4,h5,h6 {font-size:100%;font-weight:normal} 
q:before,q:after {content:''} 
abbr,acronym { border:0}
.odiv{position:relative;}
.odiv ul li{width:200px; height:100px; background:yellow; margin-bottom:20px; border:2px solid #000;}
#li1{opacity:0.3;filter:alpha(opacity:30);}
</style>
</head>

<body>
<div id="odiv" class="odiv">
    <ul>
        <li id="li1"></li>
        <li id="li2"></li>
    </ul>
</div>
</body>
</html>
<script language="javascript">
window.onload = function(){
    var li1 = document.getElementById('li1');
    var li2 = document.getElementById('li2');
    li1.onmouseover = function(){
       startMov(this,100,'opacity');
    };
    li1.onmouseout = function(){
       startMov(this,30,'opacity');
    };
    li2.onmouseover = function(){
       startMov(this,200,'height');
    };
    li2.onmouseout = function(){
       startMov(this,100,'height');
    }
    li1.timer = null;
    li2.timer = null;
    function startMov(obj,itarget,attr){
       clearInterval(obj.timer);//執行動畫以前清除動畫
       obj.timer = setInterval(function(){
          var icur = 0;
          if(attr == 'opacity'){
            icur = Math.round(parseFloat(getStyle(obj,attr))*100);//轉換成整數,而且四捨五入下
            //計算機在計算小數的時候每每是不許確的!
          }
          else{
          icur = parseInt(getStyle(obj,attr));
          }
          var speed =0;
          speed = (itarget - icur)/8;
          speed = speed>0?Math.ceil(speed):Math.floor(speed);
          if(icur == itarget){
           clearInterval(obj.timer);
          }
          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);
    }
    function getStyle(obj,attr)
    {
      if(obj.currentStyle){
        return obj.currentStyle[attr];
      }
      else{
        return getComputedStyle(obj,false)[attr];
      }
    }
}
//offsetWidth獲取的是元素實際的寬度(包括邊框和內邊距)
//只要是多物體運動,全部的屬性都不能共用
</script>
View Code

八、鏈式動畫

說明:鏈式動畫就是當前動畫執行完成後執行下一個動畫效果

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>鏈式動畫</title>
<style type="text/css">
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,tr,td {margin:0;padding:0; font-size:12px;} 
table {border-collapse:collapse;border-spacing:0;} 
fieldset,img {border:0} 
address,caption,cite,code,dfn,em,strong,th,var {font-style:normal;font-weight:normal} 
ol,ul {list-style:none} 
caption,th,td{text-align:center} 
h1,h2,h3,h4,h5,h6 {font-size:100%;font-weight:normal} 
q:before,q:after {content:''} 
abbr,acronym { border:0}
.odiv{position:relative;}
.odiv ul li{width:200px; height:100px; background:yellow; margin-bottom:20px; border:2px solid #000;}
#li1{opacity:0.3;filter:alpha(opacity:30);}
</style>
</head>
<body>
<div id="odiv" class="odiv">
    <ul>
        <li id="li1"></li>
    </ul>
</div>
</body>
</html>
<script language="javascript">
window.onload = function(){
    var li1 = document.getElementById('li1');
    li1.onmouseover = function(){
       startMov(li1,400,'width',function(){
         startMov(li1,200,'height',function(){
            startMov(li1,100,'opacity');
         });
       });
    };
    li1.onmouseout = function(){
       startMov(li1,30,'opacity',function(){
         startMov(li1,100,'height',function(){
            startMov(li1,100,'width');
         });
       });
    };
    li1.timer = null;
    function startMov(obj,itarget,attr,fn){//fn回調函數
       clearInterval(obj.timer);//執行動畫以前清除動畫
       obj.timer = setInterval(function(){
          var icur = 0;
          if(attr == 'opacity'){
            icur = Math.round(parseFloat(getStyle(obj,attr))*100);//轉換成整數,而且四捨五入下
            //計算機在計算小數的時候每每是不許確的!
          }
          else{
          icur = parseInt(getStyle(obj,attr));
          }
          var speed =0;
          speed = (itarget - icur)/8;
          speed = speed>0?Math.ceil(speed):Math.floor(speed);
          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);
    }
    function getStyle(obj,attr)
    {
      if(obj.currentStyle){
        return obj.currentStyle[attr];
      }
      else{
        return getComputedStyle(obj,false)[attr];
      }
    }
}
//offsetWidth獲取的是元素實際的寬度(包括邊框和內邊距)
//只要是多物體運動,全部的屬性都不能共用
</script>
View Code

九、多物體同時運動動畫(支持鏈式動畫)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>多物體同時運動動畫</title>
<style type="text/css">
body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,tr,td {margin:0;padding:0; font-size:12px;} 
table {border-collapse:collapse;border-spacing:0;} 
fieldset,img {border:0} 
address,caption,cite,code,dfn,em,strong,th,var {font-style:normal;font-weight:normal} 
ol,ul {list-style:none} 
caption,th,td{text-align:center} 
h1,h2,h3,h4,h5,h6 {font-size:100%;font-weight:normal} 
q:before,q:after {content:''} 
abbr,acronym { border:0}
.odiv{position:relative;}
.odiv ul li{width:200px; height:100px; background:yellow; margin-bottom:20px; border:2px solid #000;}
#li1{opacity:0.3;filter:alpha(opacity:30);}
</style>
</head>
<body>
<div id="odiv" class="odiv">
    <ul>
        <li id="li1"></li>
    </ul>
</div>
</body>
</html>
<script language="javascript">
window.onload = function(){
    var li1 = document.getElementById('li1');
    li1.onmouseover = function(){
       startMov(li1,{width:201,height:200,opacity:100});
    };
    li1.onmouseout = function(){
       startMov(li1,{width:200,height:100,opacity:30});
    };
    li1.timer = null;
    function startMov(obj,json,fn){//fn回調函數
       clearInterval(obj.timer);//執行動畫以前清除動畫
       var flag = true;//是否動畫都完成了
       obj.timer = setInterval(function(){
         for(var attr in json){
          var icur = 0;
          if(attr == 'opacity'){
            icur = Math.round(parseFloat(getStyle(obj,attr))*100);//轉換成整數,而且四捨五入下
            //計算機在計算小數的時候每每是不許確的!
          }
          else{
          icur = parseInt(getStyle(obj,attr));
          }
          var speed =0;
          speed = (json[attr] - icur)/8;
          speed = speed>0?Math.ceil(speed):Math.floor(speed);
          if(icur != json[attr]){
           flag = false;
          }
          if(attr == 'opacity'){
            obj.style.filter = 'alpha(opacity:'+(icur+speed)+')';
            obj.style.opacity = (icur+speed)/100;
          }
          else{
          obj.style[attr] = icur+speed+'px';
          }
          if(flag){
            clearInterval(obj.timer);
            if(fn){
              fn();
            }
          }
        }
       },30);
    }
    function getStyle(obj,attr)
    {
      if(obj.currentStyle){
        return obj.currentStyle[attr];
      }
      else{
        return getComputedStyle(obj,false)[attr];
      }
    }
}
//offsetWidth獲取的是元素實際的寬度(包括邊框和內邊距)
//只要是多物體運動,全部的屬性都不能共用
</script>

最後一個動畫效果完善了上述全部動畫的代碼,本身能夠根據上述的代碼進行擴展!

課程視頻地址:http://www.imooc.com/learn/167

相關文章
相關標籤/搜索