旋轉木馬案例—陣列和動畫的聯合應用
阿新 • • 發佈:2018-12-21
要點:
1.這個例子中的陣列操作的四個方法,都是在進行運算之後,都有返回值,而這些返回值有所不同。執行刪除相關的操作時,返回的是被刪除的值,而追加到陣列物件中,返回的是被操作後的整個陣列。
2.關鍵點是,在點選切換按鈕後,原來圖片陣列對應的圖片發生了改變,但是通過js獲取到的多個li標籤組成的偽陣列的每個li的樣式並沒有改變,需要重新將樣式改變一下。
程式碼:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <link rel="stylesheet" type="text/css" href="css22.css"> </head> <body> <div class="wrap" id="wrap"> <div class="slide" id="slide"> <ul> <li><a href="#"><img src="images22/slidepic1.jpg"></a></li> <li><a href="#"><img src="images22/slidepic2.jpg"></a></li> <li><a href="#"><img src="images22/slidepic3.jpg"></a></li> <li><a href="#"><img src="images22/slidepic4.jpg"></a></li> <li><a href="#"><img src="images22/slidepic5.jpg"></a></li> </ul> <div class="arrow" id="arrow"> <a href="javascript:;" class="prev" id="arrLeft"></a> <a href="javascript:;" class="next" id="arrRight"></a> <!-- 圖片兩側的大箭頭,通過prev和next兩個類進行定義 --> </div> </div> </div> <script type="text/javascript"> function myGet(id){ return document.getElementById(id); } window.onload = function(){ var liObjs = myGet("slide").getElementsByTagName("LI"); // 標籤的返回值,一般是標籤名的大寫,也大寫較好 var flag = true; // 控制動畫,一次執行完再點切換才能實現切換 function assign(){ for(var i=0;i<liObjs.length;i++){ animate(liObjs[i],config[i],function(){ flag = true; // 當點選按鈕時候,已經被賦值為flase不會執行函式,動畫函式執行完成了,再將flag設為true }); // config[]陣列提前寫好樣式,內部由多個json物件構成 } } assign(); // assign:分配 myGet("arrRight").onclick = function(){ if(flag){ flag = false; // 首先將flag改為false不會將點選事件儲存 config.push(config.shift()); assign(); // 通過這兩組陣列操作的方法,都會返回一個處理完成之後的陣列 } } myGet("arrLeft").onclick = function(){ if(flag){ flag = false; config.unshift(config.pop()); assign(); // 原來顯示的圖片的順序,通過assign()操作完成之後,原來通過陣列遍歷的陣列的圖片還是原來一樣 } } myGet("wrap").onmouseover = function(){ animate(myGet("arrow"),{"opacity":1}); // 滑鼠放上後透明度逐漸為1 } myGet("wrap").onmouseout = function(){ animate(myGet("arrow"),{"opacity":0}); // 滑鼠離開後透明度逐漸為0,達到隱藏的效果,而不是直接設定顯示或隱藏,這樣會體驗更好 } } var config = [ { width: 400, top: 20, left: 50, opacity: 0.2, zIndex: 2 },//0 { width: 600, top: 70, left: 0, opacity: 0.8, zIndex: 3 },//1 { width: 800, top: 100, left: 200, opacity: 1, zIndex: 4 },//2 { width: 600, top: 70, left: 600, opacity: 0.8, zIndex: 3 },//3 { width: 400, top: 20, left: 750, opacity: 0.2, zIndex: 2 }//4 ]; 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(element.intervalName); // 所有的動畫執行完成之後,可以再執行一個函式 if(fn){ fn(); } // 這裡呼叫的函式,也可以是本身這個函式,還可以 進行多次動畫 } },30) } function getStyle(element,attr){ return window.getComputedStyle ? window.getComputedStyle(element,null)[attr] : element.currentStyle[attr]; // 將原來的if-else語句進行判斷也相容程式碼的方式,進行簡化,寫成三目運算子的方式 // 屬性後面的[attr]是跟點語法的作用是一樣的,但是這裡不能使用點語法獲取attr的物件屬性,因為attr是變數只有用[]接收不同型別字串 // 獲取的計算後的樣式都是帶有單位的 } </script> </body> </html>
效果: