javascript基础(二级菜单练习)(四十六)

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;
}


  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

咸鸭蛋炒饭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值