javascript - 如何在没有 jquery 的情况下使用仅使用 javascript 的 EventListener 切换子菜单?
问题描述
我对 javacript 很陌生,我正在尝试编写有关使用 EventListener 切换子菜单的代码。当用户单击主题时,我的子主题隐藏了当用户单击主题或单击网页中的任何位置时,我希望子主题元素显示并再次隐藏自己。
我搜索过这个主题,大多数人都在使用 classList,因为它是最支持的浏览器。但是当我运行代码时,它对我不起作用。我试图弄清楚,但我真的做不到。
我的经验很差,也尽我所能,所以我需要人们的帮助。如果有人想给我一些建议,我将不胜感激,谢谢。
这是我的代码,请看一下。
var subTopics = document.getElementById("subtopics");
subTopics.addEventListener("click", function () {
subTopics.classList.add("show");
});
body {
margin: 0;
}
li, a{
text-decoration: none;
list-style-type: none;
text-decoration-line: none;
color: black;
}
/*main-menu*/
#mainmenu {
position: relative;
}
#mainmenu ul {
margin: 0;
padding: 0;
}
#mainmenu li {
display: inline-block;
}
#mainmenu a {
display: block;
width: 100px;
padding: 10px;
border: 1px solid;
text-align: center;
}
/*sub-topics*/
#subtopics {
position: absolute;
display: none;
margin-top: 10px;
width: 100%;
left: 0;
}
.show {
display: block;
}
.hidden {
display: none;
}
#subtopics ul {
margin: 0;
padding: 0;
}
#subtopics li {
display: block;
}
#subTopics a {
text-align: left;
}
/*columns*/
#column1, #column2, #column3 {
position: relative;
float: left;
left: 125px;
margin: 0px 5px 0px 0px;
}
/*hover underline*/
#mainmenu li:hover {
text-decoration: underline;
}
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
<link rel="stylesheet" type="text/css" href="index2.css" />
</head>
<body>
<div id="mainmenu">
<ul>
<li><a href="">Logo</a></li>
<li><a href="">Home</a></li>
<li><a href="">Topics</a>
<div id="subtopics">
<div id="column1" class="columns">
<ul>
<li><a href="">example1</a></li>
<li><a href="">example2</a></li>
<li><a href="">example3</a></li>
</ul>
</div>
</div>
</li>
</ul>
</div>
<script src="index2.js"></script>
</body>
</html>
解决方案
您向隐藏元素 ( ) 添加了单击事件,#subtopics
但无法单击隐藏元素。
这里有一个建议来展示你可以怎么做,我在其中添加了一个类li
,并在其上切换show
类。
请参阅示例 1 的 CSS 和脚本中的注释
样品 1
var subTopics = document.querySelector(".subtopics"); // target the li
subTopics.addEventListener("click", function (e) { // passed "e" to get the event
e.preventDefault(); // prevent anchor to navigate
subTopics.classList.toggle("show"); // changed to toggle for the
// the purpose of this demo
});
body {
margin: 0;
}
li, a{
text-decoration: none;
list-style-type: none;
text-decoration-line: none;
color: black;
}
/*main-menu*/
#mainmenu {
position: relative;
}
#mainmenu ul {
margin: 0;
padding: 0;
}
#mainmenu li {
display: inline-block;
}
#mainmenu a {
display: block;
width: 100px;
padding: 10px;
border: 1px solid;
text-align: center;
}
/*sub-topics*/
#subtopics {
position: absolute;
display: none;
margin-top: 10px;
width: 100%;
left: 0;
}
.subtopics.show #subtopics { /* changed */
display: block;
}
.hidden {
display: none;
}
#subtopics ul {
margin: 0;
padding: 0;
}
#subtopics li {
display: block;
}
#subTopics a {
text-align: left;
}
/*columns*/
#column1, #column2, #column3 {
position: relative;
float: left;
left: 125px;
margin: 0px 5px 0px 0px;
}
/*hover underline*/
#mainmenu li:hover {
text-decoration: underline;
}
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
<link rel="stylesheet" type="text/css" href="index2.css" />
</head>
<body>
<div id="mainmenu">
<ul>
<li><a href="#">Logo</a></li>
<li><a href="#">Home</a></li>
<li class="subtopics"><a href="#">Topics</a>
<div id="subtopics">
<div id="column1" class="columns">
<ul>
<li><a href="">example1</a></li>
<li><a href="">example2</a></li>
<li><a href="">example3</a></li>
</ul>
</div>
</div>
</li>
</ul>
</div>
<script src="index2.js"></script>
</body>
</html>
样品 2
更通用的方法可能如下所示
var submenus = document.querySelectorAll(".hassubmenu");
for (var i = 0; i < submenus.length; i++) {
submenus[i].addEventListener("click", function (e) {
e.preventDefault();
e.stopPropagation();
var last = this.closest('ul').querySelector('.show');
if (last && last !== this) last.classList.remove("show");
this.classList.toggle("show");
});
}
// added based on a comment, this will also hide any menu when clicked anywhere else
document.addEventListener("click", function () {
var last = document.querySelector('#mainmenu .show');
if (last) last.classList.remove("show");
});
body {
margin: 0;
}
li, a{
text-decoration: none;
list-style-type: none;
text-decoration-line: none;
color: black;
}
/*main-menu*/
#mainmenu {
position: relative;
}
#mainmenu ul {
margin: 0;
padding: 0;
}
#mainmenu li {
display: inline-block;
}
#mainmenu a {
display: block;
width: 100px;
padding: 10px;
border: 1px solid;
text-align: center;
}
/*sub-topics*/
.submenu {
position: absolute;
display: none;
margin-top: 10px;
width: 100%;
left: 0;
}
.hassubmenu.show .submenu { /* changed */
display: block;
}
.hidden {
display: none;
}
.submenu ul {
margin: 0;
padding: 0;
}
.submenu li {
display: block;
}
.submenu a {
text-align: left;
}
/*columns*/
#column1, #column2, #column3 {
position: relative;
float: left;
left: 125px;
margin: 0px 5px 0px 0px;
}
/*hover underline*/
#mainmenu li:hover {
text-decoration: underline;
}
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
<link rel="stylesheet" type="text/css" href="index2.css" />
</head>
<body>
<div id="mainmenu">
<ul>
<li><a href="#">Logo</a></li>
<li><a href="#">Home</a></li>
<li class="hassubmenu"><a href="#">Topics</a>
<div class="submenu">
<div id="column1" class="columns">
<ul>
<li><a href="">example1</a></li>
<li><a href="">example2</a></li>
<li><a href="">example3</a></li>
</ul>
</div>
</div>
</li>
<li class="hassubmenu"><a href="#">Services</a>
<div class="submenu">
<div id="column2" class="columns">
<ul>
<li><a href="">example4</a></li>
<li><a href="">example5</a></li>
<li><a href="">example6</a></li>
</ul>
</div>
</div>
</li>
</ul>
</div>
<script src="index2.js"></script>
</body>
</html>