我tm是万万没想到这么简单的JS demo会踩坑,而且踩坑的点是在CSS盒子层次的问题。经过逐行对照案例的JS、HTML、CSS,才发现是我CSS少了一句position:absolute,导致原本期望在上面的盒子(ul)被另一个绝对定位的盒子(span.cloud)压住。
简化了一下代码:
<!DOCTYPE html>
<html lang="en">
<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>Document</title>
<style>
* {
padding: 0;
margin: 0;
}
nav {
position: relative;
width: 500px;
height: 70px;
margin: 100px auto 0;
background-color: grey;
}
.cloud {
z-index: 1;
position: absolute;
top: 50%;
left: 0;
transform: translateY(-50%);
width: 50px;
height: 30px;
background-color: green;
opacity: 0.4;
}
ul {
z-index: 2;
position: absolute;
list-style: none;
/* background-color: pink; */
/* opacity: 1; */
}
ul li {
float: left;
padding: 20px;
}
</style>
</head>
<body>
<nav>
<!-- cloud 作为背景,放在下层,先书写 -->
<!-- <span class='cloud'></span> -->
<!-- ul必须由宽高才能在层次上遮挡cloud,但要透明才能在视觉上显示cloud背景 -->
<!-- 这个宽高遮挡作用不能由li代替,li级别不如span -->
<ul>
<li><a href="javascript:;">abcde</a></li>
<li><a href="javascript:;">abcde</a></li>
<li><a href="javascript:;">abcde</a></li>
<li><a href="javascript:;">abcde</a></li>
<li><a href="javascript:;">abcde</a></li>
<li style="float: none; padding: 0;clear:both;"></li>
</ul>
<!-- cloud 作为背景,如写在后面,需要z-index调整到下面 -->
<span class='cloud'></span>
</nav>
<script>
window.addEventListener('load', function () {
var nav = document.querySelector('nav');
var ul = document.querySelector('ul');
nav.addEventListener('mouseover', function (e) {
console.log(['mouseover', e.target.tagName]);
});
nav.addEventListener('mouseout', function (e) {
console.log(['mouseout', e.target.tagName]);
});
});
</script>
</body>
</html>
目标:正常的、不会干扰JS代码的盒子层次,应该是:nav在最底部,往上是cloud,再往上是ul,ul的子元素li自然更高一点。主要是ul在盒子层次上要比cloud高,层次上能够遮挡;同时注意视觉上是透明的,可以看到底下的cloud。
验证:当然,上面说的都是盒子堆叠的层次,要验证这个层次是否正确,还得利用事件流父子层次(mouseover/mouseout监听并打印事件的target)。
如果盒子堆叠的层次正确,将鼠标移动到ul、li上只会触发nav、ul、li、a,而不会触发cloud,因为ul和cloud是兄弟而且要把cloud压在下面。形成的冒泡事件流就是:a->li->ul->nav。
注意,即使li有高度而ul无高度(li浮动、应该clearfix或强制给ul设置高度),li是不能代替ul去压住cloud的。这时候冒泡事件流:a->li/cloud->nav,混杂了cloud进来,cloud反而会压住li、a,从而导致li触发的mouseover退出转为mouseout。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。