1. 程式人生 > >旋轉木馬案例—陣列和動畫的聯合應用

旋轉木馬案例—陣列和動畫的聯合應用

要點:

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>

效果: