英文:
Professional menu with JavaScript and jQuery (The last part)
问题
在我的以前的问题中,借助Michael M.的帮助,我解决了我的网站菜单的所有不足之处。
但在将菜单转移到我的网站后,我意识到我的菜单不打开任何链接,所有菜单和子菜单选项都只处于显示模式。
我从与删除菜单下的链接相关的脚本中删除了以下代码,但它仍然没有帮助:
sub_menu.stopPropagation();
以下是您提供的代码的翻译。如果您需要更多的帮助,请告诉我:
let icon = document.querySelector(".icon_menu");
let nav = document.querySelector(".main_menu");
$('.back').hide();
$('.back').click(function() {
if ($(this).is(':hidden')) return;
$(this).toggle();
icon.classList = "bi bi-grid-fill icon_menu";
icon.style.left = "2%";
icon.style.color = "#a66fff";
icon.style.fontSize = "40px";
nav.style.left = '-300px';
});
icon.addEventListener("click", function() {
if (this.classList.contains("bi-grid-fill")) {
this.classList = "bi bi-x-circle-fill icon_menu";
icon.style.left = "21%";
icon.style.color = "#ff6f6f";
icon.style.fontSize = "30px";
nav.style.left = 0;
} else {
this.classList = "bi bi-grid-fill icon_menu";
icon.style left = "2%";
icon.style color = "#a66fff";
icon.style fontSize = "40px";
nav.style.left = "-300px";
}
$('.back').toggle();
});
$('.main_menu li ul').each(function() {
$(this).parent().addClass('submenu');
});
$('.submenu').click(function(event) {
if ($(event.target).is($(this).find('ul a'))) { return; }
event.preventDefault();
$(this).children('ul').slideToggle();
$(this).toggleClass('open');
});
/* CSS 样式部分不需要翻译,保持原样 */
/* HTML 部分不需要翻译,保持原样 */
你感谢了编号为Steve
(76484)的人完成了你的代码。
这段代码在HTML模式下完全正常,但当我将这段代码添加到WordPress时,出现了一个新问题。
当我将菜单引入WordPress时,只能添加一个子菜单。添加第二个子菜单并单击它后,所有子菜单将关闭,不会显示任何子菜单。
我已经将菜单代码转化为WordPress代码:
<section>
<nav id="nav">
<span class="fas fa-bars icon_menu"></span>
<aside class="main_menu">
<?php
if (has_nav_menu('top_menu')) {
wp_nav_menu(array(
'theme_location' => 'top_menu',
'menu_class' => 'menu',
'container' => false
));
}
?>
</aside>
</nav>
</section>
<div class="back"></div>
我添加到模板function
文件的代码如下:
if (!function_exists('top_navigation_menus')) {
function top_navigation_menus() {
$locations = array(
'top_menu' => __('站点菜单', 'text_domain'),
);
register_nav_menus($locations);
}
add_action('init', 'top_navigation_menus');
}
我没有更改样式,它们与上面的样式相同。
英文:
In my previous questions and with the help of Michael M., I fixed all the shortcomings of my site's menu.
But after transferring the menu to my site, I realized that my menu does not open any links and all menu and sub-menu options are only in display mode.
I deleted the following code from the scripts, which was related to deleting the link under the menu, but it still didn't help:
sub_menu.stopPropagation();
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
let icon = document.querySelector(".icon_menu");
let nav = document.querySelector(".main_menu");
$('.back').hide();
$('.back').click(function() {
if ($(this).is(':hidden')) return;
$(this).toggle();
icon.classList = "bi bi-grid-fill icon_menu";
icon.style.left = "2%";
icon.style.color = "#a66fff";
icon.style.fontSize = "40px";
nav.style.left = '-300px';
});
icon.addEventListener("click", function() {
if (this.classList.contains("bi-grid-fill")) {
this.classList = "bi bi-x-circle-fill icon_menu";
icon.style.left = "21%";
icon.style.color = "#ff6f6f";
icon.style.fontSize = "30px";
nav.style.left = 0;
} else {
this.classList = "bi bi-grid-fill icon_menu";
icon.style.left = "2%";
icon.style.color = "#a66fff";
icon.style.fontSize = "40px";
nav.style.left = "-300px";
}
$('.back').toggle();
});
$('.main_menu li ul').each(function() {
$(this).parent().addClass('submenu')
});
$('.submenu').click(function(event) {
if ($(event.target).is($(this).find('ul a'))) { return; }
event.preventDefault();
$(this).children('ul').slideToggle();
$(this).toggleClass('open');
});
<!-- language: lang-css -->
.main_menu {
position: absolute;
top: 0;
left: -300px;
bottom: 0;
z-index: 999;
background: #eee;
padding-right: 2rem;
transition: all 1s ease;
}
.icon_menu {
position: fixed;
top: 10%;
left: 2%;
font-size: 40px;
color: #a66fff;
cursor: pointer;
z-index: 99999;
transition: all 1.1s ease;
}
.main_menu ul {
list-style: none;
line-height: 60px;
font-size: 35px;
}
.main_menu ul li a {
color: #000000;
text-decoration: none;
padding-right: 15px;
padding-left: 40px;
margin-left: -60px;
margin-bottom: 10px;
}
.back {
width: 100%;
height: 100%;
position: fixed;
z-index: 9 !important;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: #00000056;
}
.main_menu ul li ul {
display: none;
}
.main_menu .submenu>a::after {
content: ' → ';
}
.main_menu .open>a::after {
content: ' ↓ ' !important;
}
<!-- language: lang-html -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.3/font/bootstrap-icons.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section>
<nav id="nav">
<span class="bi bi-grid-fill icon_menu" style="right: 46%; color: rgb(255, 255, 255); font-size: 80px;"></span>
<aside class="main_menu" style="right: 0px;">
<ul id="menu-menu-2" class="menu">
<li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-48"><a href="#"><span
class="dashicons dashicons-admin-home after-menu-image-icons"></span><span
class="menu-image-title-after menu-image-title">home</span></a></li>
<li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-49 submenu">
<a href="#"><span class="dashicons dashicons-welcome-learn-more after-menu-image-icons"></span><span
class="menu-image-title-after menu-image-title">Test text</span></a>
<ul class="sub-menu">
<li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-78"><a href="#"
class="menu-image-title-after menu-image-not-hovered"><img
src="https://localhost/site/wp-content/uploads/2023/01/Music-114.ico"
class="menu-image menu-image-title-after" alt="" decoding="async" loading="lazy" width="36"
height="36"><span class="menu-image-title-after menu-image-title">Test text</span></a></li>
<li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-82"><a href="#"
class="menu-image-title-after menu-image-not-hovered"><img
src="https://localhost/site/wp-content/uploads/2023/01/Hardware-Devices-316.ico"
class="menu-image menu-image-title-after" alt="" decoding="async" loading="lazy" width="16"
height="16"><span class="menu-image-title-after menu-image-title">Test text</span></a></li>
<li
class="menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-50 submenu">
<a href="#" class="menu-image-title-after menu-image-not-hovered"><img
src="https://localhost/site/wp-content/uploads/2023/01/Music-148.ico"
class="menu-image menu-image-title-after" alt="" decoding="async" loading="lazy" width="36"
height="36"><span class="menu-image-title-after menu-image-title">Test text</span></a>
<ul class="sub-menu">
<li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-77"><a href="#"
class="menu-image-title-after menu-image-not-hovered"><img
src="https://localhost/site/wp-content/uploads/2023/01/button-yellow.ico"
class="menu-image menu-image-title-after" alt="" decoding="async" loading="lazy" width="16"
height="16"><span class="menu-image-title-after menu-image-title">Test text</span></a></li>
<li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-169"><a href="#">Test
text</a></li>
<li
class="menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-170 submenu">
<a href="#">Test text</a>
<ul class="sub-menu">
<li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-80"><a href="#"
class="menu-image-title-after menu-image-not-hovered"><img
src="https://localhost/site/wp-content/uploads/2023/01/Star-27.ico"
class="menu-image menu-image-title-after" alt="" decoding="async" loading="lazy" width="36"
height="36"><span class="menu-image-title-after menu-image-title">Test text</span></a></li>
<li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-168"><a href="#">Test
text</a></li>
<li
class="menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-167 submenu">
<a href="#">Test text</a>
<ul class="sub-menu">
<li
class="menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-166 submenu">
<a href="#">Test text</a>
<ul class="sub-menu">
<li
class="menu-item menu-item-type-custom menu-item-object-custom menu-item-has-children menu-item-52 submenu">
<a href="#" class="menu-image-title-after menu-image-not-hovered"><img
src="https://localhost/site/wp-content/uploads/2023/01/Hardware-Devices-316.ico"
class="menu-image menu-image-title-after" alt="" decoding="async" loading="lazy"
width="16" height="16"><span class="menu-image-title-after menu-image-title">Test
text</span></a>
<ul class="sub-menu">
<li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-79"><a
href="#" class="menu-image-title-after menu-image-not-hovered"><img
src="https://localhost/site/wp-content/uploads/2023/01/Firefox-4.ico"
class="menu-image menu-image-title-after" alt="" decoding="async" loading="lazy"
width="36" height="36"><span class="menu-image-title-after menu-image-title">Test
text</span></a></li>
<li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-81"><a
href="#" class="menu-image-title-after menu-image-not-hovered"><img
src="https://localhost/site/wp-content/uploads/2023/01/Music-161.ico"
class="menu-image menu-image-title-after" alt="" decoding="async" loading="lazy"
width="36" height="36"><span class="menu-image-title-after menu-image-title">Test
text</span></a></li>
<li class="menu-item menu-item-type-custom menu-item-object-custom menu-item-163"><a
href="#">Test text</a></li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</aside>
</nav>
</section>
<!-- end snippet -->
Many thanks to Steve
(76484) for completing my code.
This code works perfectly fine in HTML mode, but when I add this code to WordPress, a new problem occurs.
When I introduce the menu to WordPress, only one sub-menu can be added to it. By adding the second sub-menu and clicking on it, all the sub-menus will be closed and no sub-menu will be displayed.
The menu code that I converted to WordPress code:
<section>
<nav id="nav">
<span class="fas fa-bars icon_menu"></span>
<aside class="main_menu">
<?php
if ( has_nav_menu( 'top_menu' ) ) {
wp_nav_menu( array(
'theme_location' => 'top_menu',
'menu_class' => 'menu',
'container' => false
) );
}
?>
</aside>
</nav>
</section>
<div class="back"></div>
The code I added to my template function
file:
if ( !function_exists( 'top_navigation_menus' ) ) {
function top_navigation_menus() {
$locations = array(
'top_menu' => __( 'Site menu', 'text_domain' ),
);
register_nav_menus( $locations );
}
add_action( 'init', 'top_navigation_menus' );
}
I did not change the styles and they are the same as the styles above.
答案1
得分: 2
我不确定你是否需要在你的.submenu
点击处理程序中使用.stopPropagation()
或.preventDefault()
调用。
我建议在该处理程序中添加一个检查,检查点击的target
是否是<ul>
内的<a>
,如果是,则不执行函数体的其余部分,也就是不打开/关闭子菜单。
更新
为了防止li.submenu > a
的点击跟随href,你需要重新添加event.preventDefault()
。下面的代码片段已经更新。
let icon = document.querySelector(".icon_menu");
let nav = document.querySelector(".main_menu");
$('.back').hide();
$('.back').click(function() {
if ($(this).is(':hidden')) return;
$(this).toggle();
icon.classList = "bi bi-grid-fill icon_menu";
icon.style.left = "2%";
icon.style.color = "#a66fff";
icon.style.fontSize = "40px";
nav.style.left = '-300px';
});
icon.addEventListener("click", function() {
if (this.classList.contains("bi-grid-fill")) {
this.classList = "bi bi-x-circle-fill icon_menu";
icon.style.left = "21%";
icon.style.color = "#ff6f6f";
icon.style.fontSize = "30px";
nav.style.left = 0;
} else {
this.classList = "bi bi-grid-fill icon_menu";
icon.style left = "2%";
icon.style color = "#a66fff";
icon.style fontSize = "40px";
nav.style left = "-300px";
}
$('.back').toggle();
});
$('.main_menu li ul').each(function() {
$(this).parent().addClass('submenu')
});
$('.submenu').click(function(event) {
if ($(event.target).is($(this).find('ul a'))) { return; }
event.preventDefault();
$(this).children('ul').slideToggle();
$(this).toggleClass('open');
});
请注意,这是关于如何更新你的代码以包括event.preventDefault()
的说明。
另一个更新
我们可以通过明确地定位每个li.submenu
中的第一个<a>
来简化所有这些。我们可以用以下代码替换.submenu
的点击处理程序:
$('li.submenu > a').click(function(event) {
const $submenu = $(this).parent();
$submenu.children('ul').slideToggle();
$submenu.toggleClass('open');
event.preventDefault();
});
在这里可以看到示例fiddle。
英文:
I am not sure that you need the .stopPropagation()
or .preventDefault()
calls in your .submenu
click handler.
I would just add a guard to that handler that checks whether the target
of the click was an <a>
within the <ul>
, and if so, do not execute the rest of the function body - the opening/closing of the submenu.
Update
To prevent the click of the li.submenu > a
from following the href you would need to add the event.preventDefault()
back. The snippet below has been updated.
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
let icon = document.querySelector(".icon_menu");
let nav = document.querySelector(".main_menu");
$('.back').hide();
$('.back').click(function() {
if ($(this).is(':hidden')) return;
$(this).toggle();
icon.classList = "bi bi-grid-fill icon_menu";
icon.style.left = "2%";
icon.style.color = "#a66fff";
icon.style.fontSize = "40px";
nav.style.left = '-300px';
});
icon.addEventListener("click", function() {
if (this.classList.contains("bi-grid-fill")) {
this.classList = "bi bi-x-circle-fill icon_menu";
icon.style.left = "21%";
icon.style.color = "#ff6f6f";
icon.style.fontSize = "30px";
nav.style.left = 0;
} else {
this.classList = "bi bi-grid-fill icon_menu";
icon.style.left = "2%";
icon.style.color = "#a66fff";
icon.style.fontSize = "40px";
nav.style.left = "-300px";
}
$('.back').toggle();
});
$('.main_menu li ul').each(function() {
$(this).parent().addClass('submenu')
});
$('.submenu').click(function(event) {
if ($(event.target).is($(this).find('ul a'))) { return; }
event.preventDefault();
$(this).children('ul').slideToggle();
$(this).toggleClass('open');
});
<!-- language: lang-css -->
.main_menu {
position: absolute;
top: 0;
left: -300px;
bottom: 0;
z-index: 999;
background: #eee;
padding-right: 2rem;
transition: all 1s ease;
}
.icon_menu {
position: fixed;
top: 10%;
left: 2%;
font-size: 40px;
color: #a66fff;
cursor: pointer;
z-index: 99999;
transition: all 1.1s ease;
}
.main_menu ul {
list-style: none;
line-height: 60px;
font-size: 35px;
}
.main_menu ul li a {
color: #000000;
text-decoration: none;
padding-right: 15px;
padding-left: 40px;
margin-left: -60px;
margin-bottom: 10px;
}
.back {
width: 100%;
height: 100%;
position: fixed;
z-index: 9 !important;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: #00000056;
}
.main_menu ul li ul {
display: none;
}
.main_menu .submenu>a::after {
content: ' → ';
}
.main_menu .open>a::after {
content: ' ↓ ' !important;
}
<!-- language: lang-html -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.3/font/bootstrap-icons.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section>
<nav id="nav">
<span class="bi bi-grid-fill icon_menu"></span>
<aside class="main_menu">
<ul>
<li>
<a href="#">home</a>
</li>
<li>
<a href="#">our articles</a>
<ul>
<li>
<a href="#">social</a>
</li>
<li>
<a href="#">Academic</a>
</li>
<li>
<a href="#">historical</a>
</li>
</ul>
</li>
<li><a href="#">about us</a></li>
</ul>
</aside>
</nav>
</section>
<div class="back"></div>
<!-- end snippet -->
Another Update
We can simplify all of this by explicitly targeting the first <a>
within each li.submenu
. We replace the .submenu
click handler with:
$('li.submenu > a').click(function(event) {
const $submenu = $(this).parent();
$submenu.children('ul').slideToggle();
$submenu.toggleClass('open');
event.preventDefault();
});
See example fiddle here.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论