首页 > 解决方案 > 如何在没有 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>

标签: javascripthtmlcss

解决方案


您向隐藏元素 ( ) 添加了单击事件,#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>


推荐阅读