<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>二级菜单</title>
<style>
* {
padding: 0;
margin: 0;
}
.sdmenu {
width: 200px;
margin: 30px auto;
overflow: hidden;
background-color: #e2dfdf;
border-radius: 15px;
}
.collapsed {
height: 31px;
overflow: hidden;
}
.sdmenu div span {
display: block;
height: 30px;
line-height: 25px;
padding: 0 10px;
color: #fff;
cursor: pointer;
background-color: #3c3c3c;
border-bottom: 1px solid #e2dfdf;
}
.sdmenu div a {
display: block;
height: 30px;
line-height: 30px;
padding: 0 10px;
text-decoration: none;
font-size: 14px;
border-bottom: 1px solid #c3c3c3;
}
.sdmenu div a:hover {
background-color: #616060;
color: #fff;
}
</style>
<script src="../js/tools.js"></script>
<script>
window.onload = function () {
var menuSpan = document.getElementsByTagName("span");
var my_menu = document.getElementById("my_menu");
var collapeds = my_menu.children;
var num;
var op = 0;
for (var i = 0; i < menuSpan.length; i++) {
menuSpan[i].num = i;
menuSpan[i].onclick = function () {
i = this.num;
toggleMenu(collapeds[i]);
//判断collapeds[i] 和 collapeds[op]是否相同
if (
collapeds[i] != collapeds[op] &&
!hasClass(collapeds[op], "collapsed")
) {
/*
为了可以统一处理动画过渡效果,这里也使用toggleClass
但是这里的toggleClass()不需要移除功能,所以需要加一个判断条件
*/
//addClass(collapeds[op], "collapsed");
//toggleClass(collapeds[op], "collapsed");
toggleMenu(collapeds[op]);
}
op = i;
};
}
//创建一个方法来切换菜单的显示和折叠
function toggleMenu(obj) {
//在切换之前获取元素高度
var begin = obj.offsetHeight;
toggleClass(obj, "collapsed");
//在切换类之后获取元素的高度
var end = obj.offsetHeight;
/*
效果是将高度从begin到end过渡
将元素高度重置为begin
*/
obj.style.height = begin + "px";
move(obj, "height", 20, end, 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>
tools.js
//尝试创建一个可以执行简单动画的函数
/*
参数:
obj 要执行动画的对象
attr 要执行动画的样式
target 执行动画的目标位置
speed 速度
callback 回调函数,将会在动画执行完毕以后执行
*/
function move(obj, attr, speed, target, callback) {
clearInterval(obj.timer);
//判断速度的正负值
//如果从0-800移动,则speed为正
//如果从800-0移动,则speed为负
var current = parseInt(getStyle(obj, attr));
if (current > target) {
speed = -speed;
}
obj.timer = setInterval(function () {
var oldValue = getStyle(obj, attr);
var newValue = parseInt(oldValue) + speed;
if (
(speed < 0 && newValue < target) ||
(speed > 0 && newValue > target)
) {
newValue = target;
}
obj.style[attr] = newValue + "px";
if (newValue === target) {
clearInterval(obj.timer);
//动画执行完毕,调用回调函数
callback && callback();
}
}, 30);
}
function getStyle(obj, name) {
if (window.getComputedStyle) {
return getComputedStyle(obj, null)[name];
} else {
return obj.currentStyle[name];
}
}
//定义一个函数,用来向一个元素中添加指定的class属性值
/*
参数
obj 要添加class属性的函数
cn 要添加的class的值
*/
function addClass(obj, cn) {
//检查obj中是否含有cn
if (!hasClass(obj, cn)) {
obj.className += " " + cn;
}
}
/*
判断一个元素中是否含有指定的class属性值
如果有则返回true,没有则返回false
参数:
obj 要添加class属性的函数
cn 要添加的class的值
*/
function hasClass(obj, cn) {
//判断obj中有没有cn
//创建一个正则表达式
// var reg = /\bb2\b/;
var reg = new RegExp("\\b" + cn + "\\b");
return reg.test(obj.className);
}
/*
删除一个元素中指定的class属性
*/
function removeClass(obj, cn) {
//创建一个正则表达式
var reg = new RegExp("\\b" + cn + "\\b");
//删除class
obj.className = obj.className.replace(reg, "");
}
/*
toggleClass可以用来切换一个类
如果元素中具有该类,则删除
如果元素中没有该类,则添加
*/
function toggleClass(obj, cn) {
if (hasClass(obj, cn)) {
removeClass(obj, cn);
} else {
addClass(obj, cn);
}
}