1. 程式人生 > >筋斗雲案例—理解動畫和offsetLeft屬性

筋斗雲案例—理解動畫和offsetLeft屬性

要點:

1.為通過迴圈遍歷的方式,為同組的每一個物件定義相同的事件時,不要每次都通過臨時建立一個匿名事件,來將物件繫結事件,而是通過呼叫命名函式的方式

2.這個例子的lastPosition注意定義一個全域性變數,offsetLeft的距離是所呼叫的物件,距離瀏覽器視窗的左邊的距離,不是固定視窗

程式碼:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<style>
    * {
      margin: 0;
      padding: 0
    }

    ul {
      list-style: none
    }

    body {
      background-color: #333;
    }

    .nav {
      width: 800px;
      height: 42px;
      margin: 100px auto;
      background: url(images19/rss.png) right center no-repeat;
      background-color: #fff;
      border-radius: 10px;
      position: relative;
    }

    .nav li {
      width: 83px;
      height: 42px;
      text-align: center;
      line-height: 42px;
      float: left;
      cursor: pointer;
    }

    .nav span {
      position: absolute;
      top: 0;
      left: 0;
      width: 83px;
      height: 42px;
      background: url(images19/cloud.gif) no-repeat;
    }

    ul {
      position: relative;
    }
  </style>
</head>
<body>
	<div class="nav">
	  <span id="cloud"></span>
	  <ul id="navBar">
	    <li>北京校區</li>
	    <li>上海校區</li>
	    <li>廣州校區</li>
	    <li>深圳校區</li>
	    <li>武漢校區</li>
	    <li>關於我們</li>
	    <li>聯絡我們</li>
	    <li>招賢納士</li>
	  </ul>
	</div>

	<script type="text/javascript">
		function myGet(id){
			return document.getElementById(id);
		}
		
		var cloud = myGet("cloud");
		// 獲取雲彩物件
		var liObjs = myGet("navBar").children;
		// 獲取所有的li標籤物件

		for(var i=0;i<liObjs.length;i++){
			liObjs[i].onmouseover = mouseoverHandle;
			liObjs[i].onmouseout = mouseoutHandle;
			liObjs[i].onclick = clickHandle;
		}
		// 通過迴圈為每個li標籤註冊滑鼠進入滑鼠離開和點選事件
		// 通過命名函式,節省記憶體空間,不用每次都開闢空間

		function mouseoverHandle(){
			animate(cloud,this.offsetLeft);
           
		}

		var lastPosition = 0;
		// 一定要在點選事件的處理函式外部宣告這個變數,才可以在後面離開函式中呼叫這個變數
		function clickHandle(){
			lastPosition = this.offsetLeft;
			// 記錄當前位置
		}

		function mouseoutHandle(){
            animate(cloud,lastPosition);
            // 回到點選事件標記的位置
		}


		function animate(element,target){
			clearInterval(element.intervalName);
			// 每次點選移動按鈕的時候,清理定時器,將原來的定時器清理掉,不然會疊加多執行緒多個定時器,加快速度
			element.intervalName = setInterval(function(){
		        var current = element.offsetLeft;
		        // 通過.style.left不能獲取style標籤裡面的值,只能獲取到內部樣式的值
		        // 而.offsetLeft這個值,可以獲取到任何位置,div這個屬性的.left的值,不帶單位
		        var step = 80;
		        // 每次增加80畫素
		        step = current<target?step:-step;
		        // 判斷是在目標的左邊還是右邊,從而判斷是前進還是後退
		        current += step;
		        if(Math.abs(target-current)>Math.abs(step)){
		        	element.style.left = current + "px";
		        }else{
		        	clearInterval(element.intervalName);
		        	element.style.left = target + "px";
		        	// 當執行到最後一步時,如果不滿增加的長度,而再一次執行時,而又超過目標畫素的距離,
		            // 所以設定直接一步到目標距離,而不會
		        }  	
		    },30)
		} 
	</script>

</body>
</html>

效果: