通過計算樣式封裝動畫例項—多條動畫結合,多個引數變化的動畫
阿新 • • 發佈:2018-12-20
要點:
1.原來想寫animate()的多型形式的,寫到一半想起來,js不需要在宣告變數時就宣告資料型別,無法完成多型的性質,可以通過曲線方法完成多型效果,以後再說。
2.getComputerStyle計算樣式屬性,可以將setoff系列沒能獲取到的樣式屬性獲取出來,getComputerStyle能返回所呼叫物件的所有樣式鍵值對,形成一個樣式物件
3.這個例子中有原來可以改變一個引數,到後面通過物件改變多個引數,理解物件即為鍵值對的意義,同時理解var-in遍歷物件的
程式碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> *{ padding: 0; margin: 0; } input{ margin-top: 20px; } div{ margin-top: 30px; width: 225px; height: 175px; background-color: #6D1F9B; position: absolute; /*一定要是相對定位,不然寫的移動的位置不能改變而顯示出來*/ } </style> </head> <body> <input type="button" value="移動!" id="btn1"> <input type="button" value="變變變" id="btn2"> <div id="div"></div> <script type="text/javascript"> function myGet(id){ return document.getElementById(id); } myGet("btn1").onclick = function(){ animate2(myGet("div"),"top",500); } myGet("btn2").onclick = function(){ animate(myGet("div"),{"top":200,"width":500,"height":500,"left":500,"opacity":0.3},function(){ animate(myGet("div"),{"top":100,"width":200,"height":200,"left":100,"opacity":0.9})}); } function getStyle(element,attr){ return window.getComputedStyle ? window.getComputedStyle(element,null)[attr] : element.currentStyle[attr]; // 將原來的if-else語句進行判斷也相容程式碼的方式,進行簡化,寫成三目運算子的方式 // 屬性後面的[attr]是跟點語法的作用是一樣的,但是這裡不能使用點語法獲取attr的物件屬性,因為attr是變數只有用[]接收不同型別字串 // 獲取的計算後的樣式都是帶有單位的 } function animate2(element,attr,target){ clearInterval(element.intervalName); // 每次點選移動按鈕的時候,清理定時器,將原來的定時器清理掉,不然會疊加多執行緒多個定時器,加快速度 element.intervalName = setInterval(function(){ var current = parseInt(getStyle(element,attr)); // 通過getStyle()獲取的是帶有單位的屬性值,通過parseInt轉換成值型別,不用number()是因為轉換過後的可能是nun var step = 80; // 每次增加80畫素 step = current<target?step:-step; // 判斷是在目標的左邊還是右邊,從而判斷是前進還是後退 current += step; if(Math.abs(target-current)>Math.abs(step)){ element.style[attr] = current + "px"; }else{ clearInterval(element.intervalName); element.style[attr] = target + "px"; // 當執行到最後一步時,如果不滿增加的長度,而再一次執行時,而又超過目標畫素的距離, // 所以設定直接一步到目標距離,而不會 } },300) } function animate(element,json,fn){ clearInterval(element.intervalName); // 清理定時器 element,intervalName = setInterval(function(){ var flag = true; // 哈哈哈,又是這個,因為遍歷for迴圈遍歷有先後順序,要都到達指定位置才能清理計時器 for(var attr in json){ if(attr == "zIndex"){ // css中的屬性中間是連字元的屬性,在js操作中,將下劃線去掉同駝峰原則 // 層級的操作,直接賦值即可不需要其他的操作 element.style[attr] = json[attr]; }else if(attr == "opacity"){ var current = getStyle(element,attr)*100; var target = json[attr]*100; // 將attr對應的值獲取到,直接通過物件的鍵值獲取,這個引數沒有單位直接獲取值 var step = (target - current)/10; step = step>0 ? Math.ceil(step) : Math.floor(step); current += step; element.style[attr] = current/100; // 透明度不需要其他的引數,前面放大100倍,變回來 }else{ // 其他不同的屬性 // 遍歷json陣列物件,每次將遍歷的陣列物件屬性進行設定 var current = parseInt(getStyle(element,attr)); var target = json[attr]; // 將attr對應的值獲取到,直接通過物件的鍵值獲取 var step = (target - current)/10; // 將從當前位置到目標距離走十分之一 step = step>0 ? Math.ceil(step) : Math.floor(step); // Math.ceil()和Math.floor()分別是向上和向下取整 current += step; element.style[attr] = current + "px"; } if(current != target){ flag = false; // 也是類似於多執行緒,只有每個都為true才能到達指定位置 } } if(flag){ clearInterval(intervalName); // 所有的動畫執行完成之後,可以再執行一個函式 if(fn){ fn(); } // 這裡呼叫的函式,也可以是本身這個函式,還可以 進行多次動畫 } },300) } </script> </body> </html>
效果: