封裝了一個JS方法,支持元素的基本動畫:寬、高、透明度...等,也支持鏈式動畫和同時運動。 獲取元素的屬性的函數併進行了相容性處理: 1 function getStyle(obj, attr) { 2 if(obj.currentStyle){ //IE瀏覽器 3 return obj.curre ...
封裝了一個JS方法,支持元素的基本動畫:寬、高、透明度...等,也支持鏈式動畫和同時運動。
獲取元素的屬性的函數併進行了相容性處理:
1 function getStyle(obj, attr) { 2 if(obj.currentStyle){ //IE瀏覽器 3 return obj.currentStyle[attr]; 4 }else{ //chrome、firefox等瀏覽器 5 return getComputedStyle(obj,null)[attr]; 6 } 7 }
動畫函數:
1 var timer = null; // 聲明一個timer來存儲定時器 2 function animate(obj, Obj, callback) { 3 clearInterval(obj.timer); 4 obj.timer = setInterval(function() { 5 /* 6 * 當我們改變多個屬性時,如果其中一個屬性已經達到目標值,就會清除定時器,就會導致其他沒有達到目標值的屬性也會停止 7 * 為瞭解決這個問題,我們聲明一個節流閥flag,讓它為true 8 * 判斷是否還有沒達到目標值的屬性,如果還有,就讓flag為false(關閉節流閥),讓定時器繼續執行 9 * 當所有屬性都達到了目標值時,才執行清除定時器那一步 10 */ 11 var flag = true; 12 for(var attr in Obj) { // for...in...遍歷對象 13 var icur = 0; // 存儲獲取過來的屬性值 14 if(attr == 'opacity') { // 判斷獲取過來的屬性是否為opacity 15 icur = Math.round(parseFloat(getStyle(obj, attr)) * 100); // float會有小誤差,所以需要四捨五入一下 16 } else { 17 icur = parseInt(getStyle(obj, attr)); // 獲取過來的值可能帶單位,所以需要用到parseInt() 18 } 19 var speed = (Obj[attr] - icur) / 10; // 速度 逐漸變慢(也可以設為固定值實現勻速運動) 20 speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); // speed並不總是整數,會導致和目標值不相等,所以需要對speed進行取整,大於0向上取整,小於0向下取整 21 if(icur != Obj[attr]) { // 判斷是否還有屬性沒有達到目標值 22 flag = false; 23 } 24 if(attr == 'opacity') { // opacity是沒有單位的,所以在這裡需要判斷一下 25 obj.style.filter = 'alpha(opacity = '+ (icur + speed) +')'; 26 obj.style.opacity = (icur + speed) / 100; // opacity別忘了除以100 27 } else { 28 obj.style[attr] = icur + speed + 'px'; // 原來的值加上速度賦值給屬性 29 } 30 } 31 if(flag) { // 當所有屬性都達到目標值,即flag為true時,再停止定時器 32 clearInterval(obj.timer); 33 callback && callback(); // 判斷是否有回調函數,有的話就執行 34 } 35 }, 25) 36 }
接下來我們來調用一下:
1 var box = document.querySelector('.box'); 2 box.addEventListener("mouseover", function() { 3 animate(this, {width: 300, height: 200, opacity: 100}, function() { 4 animate(box, {width: 200, height: 100, opacity: 30}); 5 }); 6 });
結果如下: