英文:
Show / Hide (Toggle) submenus of a navigation menu using jquery doesnt work as expected
问题
我使用CSS、HTML和jQuery创建了一个单一的水平菜单。当有人单击菜单项时,它会显示一个子菜单。
我的问题是,当一个子菜单已经打开时,我单击另一个菜单项时,它会显示新的子菜单,但不会隐藏已经打开的先前菜单。
更新:我编辑了问题,现在只关注一个问题。
$(".menus_li").click(function(e) {
$(".blocks_ul", this).toggleClass('submenu-is-active');
});
a {
color: #fff;
text-decoration: none;
}
li {
list-style: none;
}
.top-menu {
z-index: 2;
position: fixed;
top: 0;
left: 0;
width: 100%;
display: flex;
width: 100%;
background: #0088ff;
padding: 1rem;
margin: 0;
}
.menus_li {
font-weight: bold;
margin-left: 1rem;
}
.blocks_ul {
display: none;
position: absolute;
background: #fff;
top: 100%;
min-width: 120px;
border-radius: 8px;
padding: 1rem;
}
.blocks_ul a {
color: #000;
}
.blocks_ul li {
padding-left: 10px;
font-weight: normal;
padding: 0.4rem 0.7rem;
}
.blocks_ul.submenu-is-active {
display: block;
}
.bg_submenu {
background-color: rgba(0, 0, 0, 0.6);
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
display: none;
}
.bg_submenu.show {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="bg_submenu"></div>
<ul class="top-menu">
<li class="menus_li"><a href="#">Cars +</a>
<ul class="blocks_ul">
<li><a class="menu-link" href="#">Mercedes</a></li>
<li><a class="menu-link" href="#">Jeep</a></li>
<li><a class="menu-link" href="#">Ford</a></li>
<li><a class="menu-link" href="#">BMW</a></li>
<li><a class="menu-link" href="#">Tesla</a></li>
</ul>
</li>
<li class="menus_li"><a href="#">Computers +</a>
<ul class="blocks_ul">
<li><a class="menu-link" href="#">Apple</a></li>
<li><a class="menu-link" href="#">Lenovo</a></li>
<li><a class="menu-link" href="#">HP</a></li>
<li><a class="menu-link" href="#">Dell</a></li>
<li><a class="menu-link" href="#">Acer</a></li>
</ul>
</li>
</ul>
英文:
I created a single horizontal menu using CSS, HTML and jquery. When someone clicks on a menu item then it displays a sub-menu.
My problem is that when a submenu is already open and I click on another menu item then it shows the new submenu but it doesn't hide the previous menu which is already open.
UPDATE: I edited the question so now is focused on one problem only.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
$(".menus_li").click(function(e) {
$(".blocks_ul", this).toggleClass('submenu-is-active');
});
<!-- language: lang-css -->
a {
color: #fff;
text-decoration: none;
}
li {
list-style: none;
}
.top-menu {
z-index: 2;
position: fixed;
top: 0;
left: 0;
width: 100%;
display: flex;
width: 100%;
background: #0088ff;
padding: 1rem;
margin: 0;
}
.menus_li {
font-weight: bold;
margin-left: 1rem;
}
.blocks_ul {
display: none;
position: absolute;
background: #fff;
top: 100%;
min-width: 120px;
border-radius: 8px;
padding: 1rem;
}
.blocks_ul a {
color: #000;
}
.blocks_ul li {
padding-left: 10px;
font-weight: normal;
padding: 0.4rem 0.7rem;
}
.blocks_ul.submenu-is-active {
display: block;
}
.bg_submenu {
background-color: rgba(0, 0, 0, 0.6);
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
display: none;
}
.bg_submenu.show {
display: block;
}
<!-- language: lang-html -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="bg_submenu"></div>
<ul class="top-menu">
<li class="menus_li"><a href="#">Cars +</a>
<ul class="blocks_ul">
<li><a class="menu-link" href="#">Mercedes</a></li>
<li><a class="menu-link" href="#">Jeep</a></li>
<li><a class="menu-link" href="#">Ford</a></li>
<li><a class="menu-link" href="#">BMW</a></li>
<li><a class="menu-link" href="#">Tesla</a></li>
</ul>
</li>
<li class="menus_li"><a href="#">Computers +</a>
<ul class="blocks_ul">
<li><a class="menu-link" href="#">Apple</a></li>
<li><a class="menu-link" href="#">Lenovo</a></li>
<li><a class="menu-link" href="#">HP</a></li>
<li><a class="menu-link" href="#">Dell</a></li>
<li><a class="menu-link" href="#">Acer</a></li>
</ul>
</li>
</ul>
<!-- end snippet -->
答案1
得分: 1
您可以按如下更改您的代码(代码中的注释):
const $blocks = $(".blocks_ul"); // 获取所有块
const $background = $(".bg_submenu"); // 获取背景
$(".menus_li").on('click', e => {
const $thisBlock = $(".blocks_ul", e.currentTarget); // 获取当前块
$blocks.not($thisBlock).removeClass('submenu-is-active'); // 从其他块中移除类
$thisBlock.toggleClass('submenu-is-active'); // 切换当前块上的类
$background.toggleClass('show', $thisBlock.hasClass('submenu-is-active')); // 仅在显示块时显示背景
});
$('body').on('click', e => {
const $clicked = $(e.target); // 获取被点击的目标
// 检查点击是否起源于菜单
if (!$clicked.hasClass('menus_li') && !$clicked.closest('.menus_li').length) {
// 如果不是,执行以下操作
$blocks.removeClass('submenu-is-active'); // 隐藏菜单
$background.removeClass('show'); // 隐藏背景
}
})
a {
color: #fff;
text-decoration: none;
}
li {
list-style: none;
}
.top-menu {
z-index: 2;
position: fixed;
top: 0;
left: 0;
width: 100%;
display: flex;
width: 100%;
background: #0088ff;
padding: 1rem;
margin: 0;
}
.menus_li {
font-weight: bold;
margin-left: 1rem;
}
.blocks_ul {
display: none;
position: absolute;
background: #fff;
top: 100%;
min-width: 120px;
border-radius: 8px;
padding: 1rem;
}
.blocks_ul a {
color: #000;
}
.blocks_ul li {
padding-left: 10px;
font-weight: normal;
padding: 0.4rem 0.7rem;
}
.blocks_ul.submenu-is-active {
display: block;
}
.bg_submenu {
background-color: rgba(0, 0, 0, 0.6);
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
display: none;
}
.bg_submenu.show {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="bg_submenu"></div>
<ul class="top-menu">
<li class="menus_li"><a href="#">Cars +</a>
<ul class="blocks_ul">
<li><a class="menu-link" href="#">Mercedes</a></li>
<li><a class="menu-link" href="#">Jeep</a></li>
<li><a class="menu-link" href="#">Ford</a></li>
<li><a class="menu-link" href="#">BMW</a></li>
<li><a class="menu-link" href="#">Tesla</a></li>
</ul>
</li>
<li class="menus_li"><a href="#">Computers +</a>
<ul class="blocks_ul">
<li><a class="menu-link" href="#">Apple</a></li>
<li><a class="menu-link" href="#">Lenovo</a></li>
<li><a class="menu-link" href="#">HP</a></li>
<li><a class="menu-link" href="#">Dell</a></li>
<li><a class="menu-link" href="#">Acer</a></li>
</ul>
</li>
</ul>
英文:
You can change your code as follows (comments in code)
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const $blocks = $(".blocks_ul"); // get all blocks
const $background = $(".bg_submenu"); // get background
$(".menus_li").on('click', e => {
const $thisBlock = $(".blocks_ul", e.currentTarget); // get current block
$blocks.not($thisBlock).removeClass('submenu-is-active'); // remove class from other blocks
$thisBlock.toggleClass('submenu-is-active'); // toggle the class on the current block
$background.toggleClass('show', $thisBlock.hasClass('submenu-is-active')); // only show the background if you are showing the block
});
$('body').on('click', e => {
const $clicked = $(e.target); // get the target that was clicked
// check if the click originated in the menu
if (!$clicked.hasClass('menus_li') && !$clicked.closest('.menus_li').length) {
// if not do the following
$blocks.removeClass('submenu-is-active'); // hide menu
$background.removeClass('show'); // hide background
}
})
<!-- language: lang-css -->
a {
color: #fff;
text-decoration: none;
}
li {
list-style: none;
}
.top-menu {
z-index: 2;
position: fixed;
top: 0;
left: 0;
width: 100%;
display: flex;
width: 100%;
background: #0088ff;
padding: 1rem;
margin: 0;
}
.menus_li {
font-weight: bold;
margin-left: 1rem;
}
.blocks_ul {
display: none;
position: absolute;
background: #fff;
top: 100%;
min-width: 120px;
border-radius: 8px;
padding: 1rem;
}
.blocks_ul a {
color: #000;
}
.blocks_ul li {
padding-left: 10px;
font-weight: normal;
padding: 0.4rem 0.7rem;
}
.blocks_ul.submenu-is-active {
display: block;
}
.bg_submenu {
background-color: rgba(0, 0, 0, 0.6);
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
display: none;
}
.bg_submenu.show {
display: block;
}
<!-- language: lang-html -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="bg_submenu"></div>
<ul class="top-menu">
<li class="menus_li"><a href="#">Cars +</a>
<ul class="blocks_ul">
<li><a class="menu-link" href="#">Mercedes</a></li>
<li><a class="menu-link" href="#">Jeep</a></li>
<li><a class="menu-link" href="#">Ford</a></li>
<li><a class="menu-link" href="#">BMW</a></li>
<li><a class="menu-link" href="#">Tesla</a></li>
</ul>
</li>
<li class="menus_li"><a href="#">Computers +</a>
<ul class="blocks_ul">
<li><a class="menu-link" href="#">Apple</a></li>
<li><a class="menu-link" href="#">Lenovo</a></li>
<li><a class="menu-link" href="#">HP</a></li>
<li><a class="menu-link" href="#">Dell</a></li>
<li><a class="menu-link" href="#">Acer</a></li>
</ul>
</li>
</ul>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论