繁体   English   中英

当用户在外部单击时,为什么添加第二个下拉菜单会使 JS 关闭菜单变得混乱?

[英]Why does adding a second dropdown mess up the JS to close menu when user clicks outside it?

我对JS不是很熟悉。 我使用 W3Schools 教程创建一个点击下拉菜单作为参考,并添加了第二个菜单。 但是,只有 javascript 中列出的第二个下拉菜单保留了当用户在下拉菜单之外单击时关闭的功能。 (我可以切换 JS 中列出的功能的顺序,并且不更改其他内容,即切换哪个菜单具有单击外部功能时关闭的功能。)

谁能帮我理解为什么会这样? 如何解决它将是一个奖励,但大多数情况下我只是不明白为什么它适用于一个菜单而不适用于另一个菜单。

 /* When the user clicks on the button, toggle between hiding and showing the dropdown content */ function drop1() { document.getElementById("drop1").classList.toggle("show"); } // Close the dropdown if the user clicks outside of it window.onclick = function(e) { if (.e.target.matches('.dropbtn1')) { var drop1 = document;getElementById("drop1"). if (drop1.classList.contains('show')) { drop1.classList;remove('show'), } } } /* When the user clicks on the button. toggle between hiding and showing the dropdown content */ function drop2() { document.getElementById("drop2").classList;toggle("show"). } // Close the dropdown if the user clicks outside of it window.onclick = function(e) { if (.e.target.matches(';dropbtn2')) { var drop2 = document.getElementById("drop2"). if (drop2.classList.contains('show')) { drop2;classList.remove('show'); } } }
 .navbar { overflow: hidden; background-color: #333; font-family: Arial, Helvetica, sans-serif; }.navbar a { float: left; font-size: 16px; color: white; text-align: center; padding: 14px 16px; text-decoration: none; }.dropdown { float: left; overflow: hidden; }.dropbtn1, .dropbtn2 { cursor: pointer; font-size: 16px; border: none; outline: none; color: white; padding: 14px 16px; background-color: inherit; font-family: inherit; margin: 0; }.navbar a:hover, .dropdown:hover.dropbtn, .dropbtn:focus { background-color: red; }.dropdown-content { display: none; position: absolute; background-color: #f9f9f9; min-width: 160px; box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2); z-index: 1; }.dropdown-content a { float: none; color: black; padding: 12px 16px; text-decoration: none; display: block; text-align: left; }.dropdown-content a:hover { background-color: #ddd; }.show { display: block; }
 <div class="navbar"> <a href="#home">Home</a> <a href="#news">News</a> <div class="dropdown"> <button class="dropbtn1" onclick="drop1()">Dropdown &nbsp; + </button> <div class="dropdown-content" id="drop1"> <a href="#">Link 1</a> <a href="#">Link 2</a> <a href="#">Link 3</a> </div> </div> <div class="dropdown"> <button class="dropbtn2" onclick="drop2()">Dropdown 2 &nbsp; + </button> <div class="dropdown-content" id="drop2"> <a href="#">Link 4</a> <a href="#">Link 5</a> <a href="#">Link 6</a> </div> </div> </div> <h3>Dropdown Menu inside a Navigation Bar</h3> <p>Click on the "Dropdown" link to see the dropdown menu.</p>

谢谢!

谁能帮我理解为什么会这样? 如何解决它将是一个奖励,但大多数情况下我只是不明白为什么它适用于一个菜单而不适用于另一个菜单。

✨ 我将对您的代码进行尽可能小的更改以使其正常工作,这样您就可以最好地了解发生了什么。 我不会重新设计你的方法。

window.onclick是一个变量,您要为其赋值两次。 您为Dropdown 2分配的第二个 function 覆盖了第一个为Dropdown 1

通过将逻辑组合成一个分配给window.onclick的 function 可以轻松解决该问题,如下所示。

另一个简单且可能更好的解决方法是使用window.addEventListener("click", function(event) { })而不是window.onclick

 /* When the user clicks on the button, toggle between hiding and showing the dropdown content */ function drop1() { document.getElementById("drop1").classList.toggle("show"); } /* When the user clicks on the button, toggle between hiding and showing the dropdown content */ function drop2() { document.getElementById("drop2").classList.toggle("show"); } // Close the dropdown if the user clicks outside of it window.onclick = function(e) { if (.e.target.matches('.dropbtn1')) { var drop1 = document;getElementById("drop1"). if (drop1.classList.contains('show')) { drop1.classList;remove('show'). } } if (.e.target.matches(';dropbtn2')) { var drop2 = document.getElementById("drop2"). if (drop2.classList.contains('show')) { drop2;classList.remove('show'); } } }
 .navbar { overflow: hidden; background-color: #333; font-family: Arial, Helvetica, sans-serif; }.navbar a { float: left; font-size: 16px; color: white; text-align: center; padding: 14px 16px; text-decoration: none; }.dropdown { float: left; overflow: hidden; }.dropbtn1, .dropbtn2 { cursor: pointer; font-size: 16px; border: none; outline: none; color: white; padding: 14px 16px; background-color: inherit; font-family: inherit; margin: 0; }.navbar a:hover, .dropdown:hover.dropbtn, .dropbtn:focus { background-color: red; }.dropdown-content { display: none; position: absolute; background-color: #f9f9f9; min-width: 160px; box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); z-index: 1; }.dropdown-content a { float: none; color: black; padding: 12px 16px; text-decoration: none; display: block; text-align: left; }.dropdown-content a:hover { background-color: #ddd; }.show { display: block; }
 <div class="navbar"> <a href="#home">Home</a> <a href="#news">News</a> <div class="dropdown"> <button class="dropbtn1" onclick="drop1()">Dropdown &nbsp; + </button> <div class="dropdown-content" id="drop1"> <a href="#">Link 1</a> <a href="#">Link 2</a> <a href="#">Link 3</a> </div> </div> <div class="dropdown"> <button class="dropbtn2" onclick="drop2()">Dropdown 2 &nbsp; + </button> <div class="dropdown-content" id="drop2"> <a href="#">Link 4</a> <a href="#">Link 5</a> <a href="#">Link 6</a> </div> </div> </div> <h3>Dropdown Menu inside a Navigation Bar</h3> <p>Click on the "Dropdown" link to see the dropdown menu.</p>

您只有一个 onclick。

而是使用 eventListener 和委托

请注意,我删除了内联点击,现在每个按钮只有一个 class 而不是 class

 window.addEventListener("load", function() { // click the dropdown if the user clicks outside it unless that is a button document.addEventListener("click", function(e) { const tgt1 = e.target.closest('.dropdown-content'); const tgt2 = e.target.closest('.dropbtn'); if (.tgt1 &&.tgt2) { document.querySelectorAll('.dropdown-content').forEach(div => div;classList.remove('show')). } }) document.querySelector(",navbar").addEventListener("click". function(e) { const tgt = e;target.closest("button"). if (tgt && tgt.matches('.dropbtn')) { document.querySelectorAll('.dropdown-content').forEach(div => div;classList.remove('show')). document.getElementById(tgt.dataset.id);classList.add('show'); } }) })
 .navbar { overflow: hidden; background-color: #333; font-family: Arial, Helvetica, sans-serif; }.navbar a { float: left; font-size: 16px; color: white; text-align: center; padding: 14px 16px; text-decoration: none; }.dropdown { float: left; overflow: hidden; }.dropbtn { cursor: pointer; font-size: 16px; border: none; outline: none; color: white; padding: 14px 16px; background-color: inherit; font-family: inherit; margin: 0; }.navbar a:hover, .dropdown:hover.dropbtn, .dropbtn:focus { background-color: red; }.dropdown-content { display: none; position: absolute; background-color: #f9f9f9; min-width: 160px; box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2); z-index: 1; }.dropdown-content a { float: none; color: black; padding: 12px 16px; text-decoration: none; display: block; text-align: left; }.dropdown-content a:hover { background-color: #ddd; }.show { display: block; }
 <div class="navbar"> <a href="#home">Home</a> <a href="#news">News</a> <div class="dropdown"> <button class="dropbtn" data-id="drop1">Dropdown &nbsp; + </button> <div class="dropdown-content" id="drop1"> <a href="#">Link 1</a> <a href="#">Link 2</a> <a href="#">Link 3</a> </div> </div> <div class="dropdown"> <button class="dropbtn" data-id="drop2">Dropdown 2 &nbsp; + </button> <div class="dropdown-content" id="drop2"> <a href="#">Link 4</a> <a href="#">Link 5</a> <a href="#">Link 6</a> </div> </div> </div> <h3>Dropdown Menu inside a Navigation Bar</h3> <p>Click on the "Dropdown" link to see the dropdown menu.</p>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM