<!DOCTYPE html>
<html lang="ch">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>二级菜单练习</title>
<script src="./tools.js"></script>
<script>
window.onload = function () {
// 获取所有的span(为兼容IE8)
var mySpan = document.querySelectorAll('.mySpan');
for (var i = 0; i < mySpan.length; i++) {
// 定义一个变量,获取当前打开的菜单
var openSpan = mySpan[0].parentNode;
mySpan[i].onclick = function () {
// 获取其父元素
var mySpanparent = this.parentNode;
// 调用执行过渡效果的函数
tsn(mySpanparent);
// 判断 mySpanparent 和 openSpan 是否相等
if (mySpanparent != openSpan && !hasClass(openSpan, 'fold')) {
// 点击菜单时,关闭上一个已经打开的菜单
// 为统一处理动画的过渡效果,我们希望将addClass改为toggleClass
// addClass(openSpan, 'fold');
// toggleClass(openSpan, 'fold');
// 调用执行过渡效果的函数
tsn(openSpan);
}
// 更新当前打开的菜单
openSpan = mySpanparent;
};
}
// 创建一个函数来完成过渡效果
function tsn(obj) {
// 在切换类之前获取元素的高度
var begin = obj.offsetHeight;
// 为菜单添加折叠效果
toggleClass(obj, 'fold');
// 在切换类之后获取元素的高度
var end = obj.offsetHeight;
// 将元素的高度重置为begin(动画效果是从begin->end)
obj.style.height = begin + 'px';
// 使用move函数
move(obj, end, 10, 'height', function () {
// 动画执行完毕,内联样式没有存在的意义,直接删除
obj.style.height = '';
});
}
};
</script>
<style>
* {
margin: 0;
padding: 0;
}
.banner {
width: 150px;
height: 500px;
margin: 0 auto;
}
.banner .first {
/* 设置圆角 */
border-radius: 5px 5px 0 0;
}
.banner .last {
border-bottom: none;
}
/* 设置span的样式 */
.banner span {
display: block;
color: white;
background-color: rgb(113, 111, 111);
/* 设置文本居中 */
text-align: center;
}
/* 设置超链接的样式 */
.banner a {
display: block;
/* 去除下划线 */
text-decoration: none;
color: rgb(47, 150, 187);
background-color: rgb(198, 200, 200);
text-align: center;
border-bottom: 1px solid rgb(0, 0, 0);
}
/* 设置鼠标移入效果 */
.banner a:hover {
background-color: aquamarine;
}
/* 设置折叠效果 */
.banner .fold {
height: 21px;
overflow: hidden;
}
</style>
</head>
<body>
<div class="banner" id="banner">
<div class="myTools">
<span class="mySpan first">在线工具</span>
<a href="javascript:;">图像优化</a>
<a href="javascript:;">收藏夹图标生成器</a>
<a href="javascript:;">邮件</a>
<a href="javascript:;">htaccess密码</a>
<a href="javascript:;">梯度图像</a>
<a href="javascript:;">按钮生成器</a>
</div>
<div class="fold">
<span class="mySpan">支持我们</span>
<a href="javascript:;">推荐我们</a>
<a href="javascript:;">联系我们</a>
<a href="javascript:;">网络资源</a>
</div>
<div class="fold">
<span class="mySpan">合作伙伴</span>
<a href="javascript:;">JavaScript工具包</a>
<a href="javascript:;">css驱动</a>
<a href="javascript:;">CodingForums</a>
<a href="javascript:;">CSS例子</a>
</div>
<div class="fold">
<span class="mySpan">测试电流</span>
<a href="javascript:;">CSS工具包</a>
<a href="javascript:;">JavaScript驱动</a>
<a href="javascript:;">AodingForums</a>
<a href="javascript:;" class="last">HTML例子</a>
</div>
</div>
</body>
</html>
下面为引入的外部文件tools.js中的内容
// 定义一个获取元素样式的函数
function getStyle(obj, name) {
if (window.getComputedStyle) {
// 其他浏览器
return getComputedStyle(obj, name)[name];
} else {
// IE浏览器
return obj.currentStyle[name];
}
}
/*
定义一个移动div的函数
- obj 执行动画的对象
target 目标位置
speed 速度
style 样式
callback 回调函数
*/
function move(obj, target, speed, style, callback) {
// 获取当前div的位置
var current = parseInt(getStyle(obj, style));
// 判断速度的正负
if (current > target) {
speed = -speed;
}
// 由于每点击一次就会开启一个定时器,所以每次都需要关闭前一个定时器
clearInterval(obj.timer);
// 创建一个定时器
obj.timer = setInterval(function () {
// 获取方块left初始值 parseInt()可以将字符串转换为数字,即获取有效值
var oldleft = parseInt(getStyle(obj, style));
// 赋予方块left新值
var newleft = oldleft + speed;
// 当到达1000px时停下
if (newleft < target && speed < 0 || newleft > target && speed > 0) {
newleft = target;
}
// 为方块left设置新值
obj.style[style] = newleft + 'px';
if (newleft == target) {
clearInterval(obj.timer);
callback && callback();
}
}, 30);
}
/*
- 定义一个函数向元素中添加指定的class属性值
参数:obj 需要添加class属性的元素
cn 需要添加的class值
*/
function addClass(obj, cn) {
// 检查obj中是否含有cn
if (!hasClass(obj, cn)) {
obj.className += ' ' + cn;
}
}
/*
- 定义一个函数判断元素中是否含有指定的class值
*/
function hasClass(obj, cn) {
// 必须用构造函数的方法创建正则表达式
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, '');
}
/*
- 定义一个函数来切换类
如果元素中有该类,则删除
如果元素中没有该类,则添加
*/
function toggleClass(obj, cn) {
if (hasClass(obj, cn)) {
removeClass(obj, cn);
} else {
addClass(obj, cn);
}
}
效果: