说明:
如果我们直接使用CSS3中的transition属性来做的话,会有一个问题。那就是我们必须规定每个二级菜单的高度,这样才能有过渡效果。但是,很多时候我们二级菜单里面的每个子项是不确定的,所以不能将高度规定死。
既然不能规定死,那么就得利用js来动态的计算二级菜单每个子项的高度了。
代码:
首先是HTML和CSS部分:
<nav class="nav">
<ul class="clearfix">
<li>
<a href="#">首页1</a>
<ul class="er">
<li><a href="#">二级菜单</a></li>
<li><a href="#">二级菜单</a></li>
</ul>
</li>
<li>
<a href="#">首页2</a>
<ul class="er">
<li><a href="#">二级菜单</a></li>
<li><a href="#">二级菜单</a></li>
<li><a href="#">二级菜单</a></li>
<li><a href="#">二级菜单</a></li>
<li><a href="#">二级菜单</a></li>
<li><a href="#">二级菜单</a></li>
</ul>
</li>
<li>
<a href="#">首页3</a>
<ul class="er">
<li><a href="#">我也是二级菜单</a></li>
<li><a href="#">我也是二级菜单</a></li>
<li><a href="#">我也是二级菜单</a></li>
<li><a href="#">我也是二级菜单</a></li>
<li><a href="#">我也是二级菜单</a></li>
<li><a href="#">我也是二级菜单</a></li>
<li><a href="#">我也是二级菜单</a></li>
<li><a href="#">我也是二级菜单</a></li>
</ul>
</li>
</ul>
</nav>
CSS部分
这儿用的单位是rem,主要原因是我用vscode的插件自动转换的,在这儿就不做更改了。
* {
margin: 0;
padding: 0;
}
li {
list-style: none;
}
a {
text-decoration: none;
}
.clearfix:after {
content: "";
display: block;
height: 0;
clear: both;
visibility: hidden;
}
.clearfix {
*zoom: 1;
}
.nav {
width: 18.75rem;
height: 3.125rem;
line-height: 3.125rem;
margin: 6.25rem auto;
background-color: #ccc;
}
.nav>ul>li {
position: relative;
float: left;
}
.nav>ul>li:hover {
background-color: skyblue;
}
.nav>ul>li>a {
padding: 0.3125rem;
}
.nav>ul>li>.er {
position: absolute;
left: 0;
top: 100%;
line-height: normal;
background-color: #ccc;
/* 隐藏盒子 */
height: 0;
overflow: hidden;
/* 解决文字菜单里面内容换行的问题 */
white-space: nowrap;
/* 谁做过渡就给谁加 */
transition: all .3s;
}
.nav>ul>li>.er>li {
padding: .3125rem;
}
.nav>ul>li>.er>li>a {
display: block;
}
.nav>ul>li>.er>li:hover {
background-color: skyblue;
}
js代码
// 写一个脚本让二级菜单自适应高度
var er = document.querySelector('.er');
// 定义一个变量用于记录子元素的高度和
var sum = 0;
var li = document.querySelectorAll('.nav>ul>li');
for (var j = 0; j < li.length; j++) {
// 需要记住触发事件的元素
var t = null;
li[j].addEventListener('mouseover', function () {
t = this.querySelector('.er');
//元素对象t存在才执行,不存在的话就不执行。
if(t){
for (var i = 0; i < t.children.length; i++) {
// 计算每一个孩子的高度,求和
sum += t.children[i].offsetHeight;
}
// 将父元素高度改变
t.style.height = sum + 'px';
}
})
li[j].addEventListener('mouseout', function () {
if(t){
t.style.height = 0 + 'px';
// 将这个值还原
sum = 0;
}
})
}