垂直下拉菜单是一种常见的网页导航模式,当用户悬停或点击父菜单项时,子菜单项会垂直展开显示。不使用jQuery意味着我们需要使用原生JavaScript和CSS来实现这一功能。
<ul class="dropdown-menu">
<li>
<a href="#">菜单项1</a>
<ul class="submenu">
<li><a href="#">子项1</a></li>
<li><a href="#">子项2</a></li>
</ul>
</li>
<li>
<a href="#">菜单项2</a>
<ul class="submenu">
<li><a href="#">子项1</a></li>
<li><a href="#">子项2</a></li>
</ul>
</li>
</ul>
.dropdown-menu {
list-style: none;
padding: 0;
margin: 0;
}
.dropdown-menu > li {
position: relative;
display: inline-block;
padding: 10px 20px;
background: #f0f0f0;
}
.dropdown-menu > li:hover {
background: #ddd;
}
.submenu {
display: none;
position: absolute;
top: 100%;
left: 0;
list-style: none;
padding: 0;
margin: 0;
min-width: 200px;
background: #fff;
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
}
.submenu li {
padding: 10px;
}
.submenu li:hover {
background: #eee;
}
/* 显示子菜单的类 */
.submenu.active {
display: block;
}
document.addEventListener('DOMContentLoaded', function() {
const menuItems = document.querySelectorAll('.dropdown-menu > li');
menuItems.forEach(item => {
const submenu = item.querySelector('.submenu');
item.addEventListener('mouseenter', function() {
submenu.classList.add('active');
});
item.addEventListener('mouseleave', function() {
submenu.classList.remove('active');
});
});
});
document.addEventListener('DOMContentLoaded', function() {
const menuItems = document.querySelectorAll('.dropdown-menu > li');
menuItems.forEach(item => {
const link = item.querySelector('a');
const submenu = item.querySelector('.submenu');
link.addEventListener('click', function(e) {
e.preventDefault();
// 关闭其他打开的子菜单
document.querySelectorAll('.submenu.active').forEach(openMenu => {
if (openMenu !== submenu) {
openMenu.classList.remove('active');
}
});
// 切换当前子菜单
submenu.classList.toggle('active');
});
});
// 点击页面其他位置关闭菜单
document.addEventListener('click', function(e) {
if (!e.target.closest('.dropdown-menu > li')) {
document.querySelectorAll('.submenu.active').forEach(menu => {
menu.classList.remove('active');
});
}
});
});
原因:父元素没有设置position: relative
,导致子菜单的绝对定位相对于文档而非父元素。
解决:确保父li
元素设置了position: relative
。
原因:鼠标在父元素和子菜单之间移动时触发了mouseleave
事件。
解决:可以给子菜单也添加mouseenter
和mouseleave
事件,或者使用CSS的:hover
伪类替代JavaScript。
原因:移动设备没有悬停状态。
解决:实现点击切换功能(如方法二所示),并添加触摸事件支持。
原因:为每个菜单项都添加了事件监听器。
解决:使用事件委托,只在父元素上添加一个事件监听器:
document.querySelector('.dropdown-menu').addEventListener('mouseover', function(e) {
if (e.target.tagName === 'LI' && e.target.querySelector('.submenu')) {
document.querySelectorAll('.submenu.active').forEach(menu => {
menu.classList.remove('active');
});
e.target.querySelector('.submenu').classList.add('active');
}
});
document.querySelector('.dropdown-menu').addEventListener('mouseout', function(e) {
if (e.target.tagName === 'LI' && e.target.querySelector('.submenu')) {
e.target.querySelector('.submenu').classList.remove('active');
}
});
通过以上方法,你可以完全不用jQuery实现一个功能完善的垂直下拉菜单。
没有搜到相关的文章