javascript基礎(二級選單練習)(四十六)

厚積薄發2017發表於2017-02-16

1html程式碼:

<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<title>二級選單</title>
		<style type="text/css">
			* {
				margin: 0;
				padding: 0;
				list-style-type: none;
			}
			
			a,img {
				border: 0;
				text-decoration: none;
			}
			
			body {
				font: 12px/180% Arial, Helvetica, sans-serif, "新宋體";
			}
		</style>

		<link rel="stylesheet" type="text/css" href="css/sdmenu.css" />
		
		<script type="text/javascript" src="js/tools.js"></script>
		<script type="text/javascript">
			
			window.onload = function(){
				
				/*
				 * 二級選單,
				 * 	點選選單以後,關閉的就展開,展開的就關閉
				 *  如果為元素新增的collapsed這類,則選單關閉,
				 * 	如果移除元素的collapsed這類,則選單展開
				 */
				
				//獲取所有的class為menuSpan的span
				var menuSpan = document.querySelectorAll(".menuSpan");
				
				//建立一個變數,來儲存當前正在開啟的選單
				var openDiv = menuSpan[0].parentNode;
				
				
				//繫結單擊響應函式
				for(var i=0 ; i<menuSpan.length ; i++){
					
					menuSpan[i].onclick = function(){
						
						//單擊選單以後,切換選單的顯示狀態
						var parentDiv = this.parentNode;
						
						//切換選單
						toggleMenu(parentDiv);
						
						/*
						 * 要求二級選單隻能有一個展開,
						 * 	所以我們在展開一個選單時,需要將之前展開的關閉
						 */
						if(openDiv != parentDiv && !hasClass(openDiv , "collapsed")){
							//關閉以開啟的div
							//addClass(openDiv , "collapsed");
							
							/*
							 * 為了統一處理過渡的效果,將這裡的addClass()也修改為toggleClass()
							 * 而這裡不需要刪除的功能,只需要新增
							 */
							//toggleClass(openDiv , "collapsed");
							toggleMenu(openDiv);
						}
						
						//修改openDiv
						openDiv = parentDiv;
						
					};
				}
				
				/*
				 * 提取一個方法,用來切換選單
				 * 	obj 要切換的選單
				 */
				function toggleMenu(obj){
					//在切換類之前,獲取一下div的高度
					var begin = obj.offsetHeight;
					
					//為當前的div新增collapsed這個類
					toggleClass(obj , "collapsed");
					
					//在切換完類之後,獲取一個div的高度
					var end = obj.offsetHeight;
					
					//console.log("begin = "+begin + " , end = "+end);
					
					//將元素的高度設定為begin
					obj.style.height = begin + "px";
					
					//通過move()函式將元素的高度向end過渡
					move(obj , "height" , end , 10 , function(){
						//動畫執行完畢,內聯樣式沒有意義,刪除之
						obj.style.height = "";
					});
				}
				
				
				
			};
			
			
		</script>
		
	</head>

	<body>

		<div id="my_menu" class="sdmenu">
			<div>
				<span class="menuSpan">線上工具</span>
				<a href="#">影象優化</a>
				<a href="#">收藏夾圖示生成器</a>
				<a href="#">郵件</a>
				<a href="#">htaccess密碼</a>
				<a href="#">梯度影象</a>
				<a href="#">按鈕生成器</a>
			</div>
			<div class="collapsed">
				<span class="menuSpan">支援我們</span>
				<a href="#">推薦我們</a>
				<a href="#">連結我們</a>
				<a href="#">網路資源</a>
			</div>
			<div class="collapsed">
				<span class="menuSpan">合作伙伴</span>
				<a href="#">JavaScript工具包</a>
				<a href="#">CSS驅動</a>
				<a href="#">CodingForums</a>
				<a href="#">CSS例子</a>
			</div>
			<div class="collapsed">
				<span class="menuSpan">測試電流</span>
				<a href="#">Current or not</a>
				<a href="#">Current or not</a>
				<a href="#">Current or not</a>
				<a href="#">Current or not</a>
			</div>
		</div>
	</body>
</html>

2.tool.js程式碼:

/*
 * 定義一個move()函式來執行一些簡單的動畫效果
 * 引數:
 * 	obj 要執行動畫的物件
 * 	attr 執行動畫時要修改的屬性
 * 	target 執行動畫的目標位置
 * 	speed 動畫執行的速度
 *  callback 回撥函式,當動畫執行完畢以後,該回撥函式會執行
 */
function move(obj, attr, target, speed, callback) {
	//關閉之前的定時器
	/*
	 * 一般都會將定時器的標識作為執行動畫物件的屬性儲存,這樣可以確保只有當前物件能訪問到定時器
	 */
	clearInterval(obj.timer);

	//判斷向左移還是向右移
	//0 --> 800 向右移
	//起始位置 < 目標位置 則向右移動,速度為正
	//800 --> 0 向左移
	//起始位置 > 目標位置 則向左移動,速度為負

	//獲取元素的起始位置
	var current = parseInt(getStyle(obj, attr));

	if(current > target) {
		//起始位置 > 目標位置 則向左移動,速度為負
		speed = -speed;
	}

	//開啟一個定時器,控制box1移動
	obj.timer = setInterval(function() {

		//獲取box1的當前的left值
		var oldValue = parseInt(getStyle(obj, attr));

		//通過舊值來計算新值
		var newValue = oldValue + speed;

		//判斷newValue是否大於800
		/*
		 * 如果從0 向 800,執行動畫,則值越來越大
		 * 如果從800向0執行動畫,則值越來小
		 */
		if((speed > 0 && newValue > target) || (speed < 0 && newValue < target)) {
			newValue = target;
		}

		//將box1的left值修改為新值
		obj.style[attr] = newValue + "px";

		//當box1移動到800px的位置時,停止移動
		if(newValue == target) {

			clearInterval(obj.timer);

			//呼叫回撥函式
			callback && callback();
		}

	}, 30);

}

/*
 * 用來獲取任意元素的當前樣式
 * 	引數:
 * 		obj 要獲取樣式的元素
 * 		name 要獲取的樣式的名字
 * 
 * 在讀取元素的樣式時,如果元素沒有設定樣式,
 * 	則火狐、Chrome等瀏覽器會自動計算元素的樣式值
 * 	而IE瀏覽器,有時用不會自動計算,而是返回預設值,比如寬度會返回auto
 * 		
 */
function getStyle(obj, name) {

	//判斷瀏覽器中是否含有getComputedStyle這個方法
	if(window.getComputedStyle) {
		//支援正常的瀏覽器
		return getComputedStyle(obj, null)[name];
	} else {
		//只支援IE
		return obj.currentStyle[name];
	}

}

/*
 * 定義一個專門用來向元素中新增class的函式
 * 	引數:
 * 		obj 要新增class屬性的物件
 * 		cn 要新增的class的屬性值
 */
function addClass(obj, cn) {

	//如果元素中有該class則不新增,沒有才新增
	if(!hasClass(obj, cn)) {
		obj.className += " " + cn;
	}

}

/*
 * 建立一個函式檢查一個元素中是否含有指定的class
 * 	如果有,則返回true。否則返回false
 */
function hasClass(obj, cn) {

	//建立正規表示式
	var reg = new RegExp("\\b" + cn + "\\b");

	//返回檢查結果
	return reg.test(obj.className);
}

/*
 * 用來從指定元素中刪除class值的方法
 */
function removeClass(obj, cn) {

	//要刪除一個class,就是將這個class替換為一個空串
	//建立正規表示式
	var reg = new RegExp("\\b" + cn + "\\b", "g");

	//判斷obj中是否含有這個class

	if(reg.test(obj.className)) {
		//將內容替換為空串
		obj.className = obj.className.replace(reg, "");
	}
}

/*
 * 用來切換元素的class的方法
 * 	如果元素中含有該class,則刪除
 * 	如果元素中沒有該class,則新增
 * 
 */
function toggleClass(obj, cn) {
	//檢查obj中是否含有cn
	if(hasClass(obj, cn)) {
		//有該class,則刪除
		removeClass(obj, cn);
	} else {
		//沒有該class,則新增
		addClass(obj, cn);
	}

}

3.sdmenu.css

@charset "utf-8";

/* sdmenu */

div.sdmenu {
	width: 150px;
	margin: 0 auto;
	font-family: Arial, sans-serif;
	font-size: 12px;
	padding-bottom: 10px;
	background: url(bottom.gif) no-repeat right bottom;
	color: #fff;
}

div.sdmenu div {
	background: url(title.gif) repeat-x;
	overflow: hidden;
}

div.sdmenu div:first-child {
	background: url(toptitle.gif) no-repeat;
}

div.sdmenu div.collapsed {
	height: 25px;
}

div.sdmenu div span {
	display: block;
	height: 15px;
	line-height: 15px;
	overflow: hidden;
	padding: 5px 25px;
	font-weight: bold;
	color: white;
	background: url(expanded.gif) no-repeat 10px center;
	cursor: pointer;
	border-bottom: 1px solid #ddd;
}

div.sdmenu div.collapsed span {
	background-image: url(collapsed.gif);
}

div.sdmenu div a {
	padding: 5px 10px;
	background: #eee;
	display: block;
	border-bottom: 1px solid #ddd;
	color: #066;
}

div.sdmenu div a.current {
	background: #ccc;
}

div.sdmenu div a:hover {
	background: #066 url(linkarrow.gif) no-repeat right center;
	color: #fff;
	text-decoration: none;
}


相關文章