📅  最后修改于: 2023-12-03 15:09:56.458000             🧑  作者: Mango
有时候在页面中,我们需要一个垂直列表,在鼠标悬停每个项目时显示子元素,但是如果鼠标在子元素中移动,子元素就会消失。这就是所谓的"悬停子元素时防止鼠标悬停"。
有多种方式可以实现这个效果,其中一种常见的方式是通过CSS的:hover
选择器和JavaScript实现。
首先,我们可以使用CSS的:hover
选择器和JavaScript来实现这个效果。以下是一个简单的示例代码:
<ul class="parent">
<li>
Item 1
<ul class="child">
<li>Child item 1</li>
<li>Child item 2</li>
<li>Child item 3</li>
</ul>
</li>
<li>
Item 2
<ul class="child">
<li>Child item 1</li>
<li>Child item 2</li>
<li>Child item 3</li>
</ul>
</li>
<li>Item 3</li>
</ul>
.parent {
list-style: none;
margin: 0;
padding: 0;
}
.parent li {
position: relative;
padding: 10px;
background-color: #eee;
cursor: pointer;
}
.parent li:hover {
background-color: #ccc;
}
.child {
position: absolute;
top: 100%;
left: 0;
display: none;
margin: 0;
padding: 0;
}
.parent li:hover .child {
display: block;
}
.child li {
padding: 5px;
background-color: #f1f1f1;
}
.child li:hover {
background-color: #ddd;
}
const parentItems = document.querySelectorAll('.parent > li');
for(let i = 0; i < parentItems.length; i++) {
parentItems[i].addEventListener('mouseover', function(e) {
e.stopPropagation();
hideAllChildren();
this.querySelector('.child').style.display = 'block';
});
}
function hideAllChildren() {
const children = document.querySelectorAll('.child');
for(let i = 0; i < children.length; i++) {
children[i].style.display = 'none';
}
}
document.addEventListener('mouseover', function() {
hideAllChildren();
});
这个代码使用了CSS的:hover
选择器和JavaScript。当鼠标悬停在父级列表项上时,子级列表项会显示出来。当鼠标离开父级列表项时,子级列表项会消失。如果鼠标移动到子级列表项上时,子级列表项也不会消失,因为我们使用了事件委托来阻止事件冒泡。
上述代码并不能防止子元素在鼠标悬停时也会消失,我们可以使用下述高级实现方式。
一个更高级的方法是使用CSS pointer-events
属性。此属性允许我们定义元素是否应响应鼠标事件,当设置为none
时,元素将不会响应鼠标事件。
以下是使用pointer-events
属性的示例代码:
.parent {
list-style: none;
margin: 0;
padding: 0;
}
.parent li {
position: relative;
padding: 10px;
background-color: #eee;
cursor: pointer;
}
.parent li:hover {
background-color: #ccc;
}
.child {
position: absolute;
top: 100%;
left: 0;
display: none;
margin: 0;
padding: 0;
}
.parent li:hover .child {
display: block;
}
.child li {
padding: 5px;
background-color: #f1f1f1;
}
.child li:hover {
background-color: #ddd;
}
.child:hover, .child:hover * {
pointer-events: none;
}
这个代码有些不同。现在我们有一个新的CSS规则:
.child:hover, .child:hover * {
pointer-events: none;
}
这个规则的作用是防止任何子元素响应鼠标事件。这样,即使鼠标悬停在子级列表项上,子级列表项仍将保持显示状态。
悬停子元素时防止鼠标悬停是一个非常有用的技术,可以帮助我们在构建垂直列表时展示更多的内容。我们可以使用CSS的:hover
选择器和JavaScript来实现这个效果,也可以使用pointer-events
属性来实现更高级的效果。