简体   繁体   English

如果单击外部则切换菜单然后隐藏

[英]Toggle menu if click outside then hide

I am trying to create a menu where clicking on the account will show the menu and clicking again will close the menu.我正在尝试创建一个菜单,单击帐户将显示菜单,再次单击将关闭菜单。 Again, if someone clicks outside the menu, the menu will close.同样,如果有人在菜单外点击,菜单将关闭。 I can do everything, but if there is a problem, even if I click on a link in the menu, the menu is closed.我可以做任何事情,但是如果出现问题,即使我点击菜单中的链接,菜单也会关闭。 I want to only close the menu if someone clicks on the account button again and outside the menu.如果有人在菜单外再次单击帐户按钮,我只想关闭菜单。 what is the solution?解决办法是什么?

 /* When the user clicks on the button, toggle between hiding and showing the dropdown content */ function myFunction() { document.getElementById("myDropdown").classList.toggle("show"); } // Close the dropdown if the user clicks outside of it window.onclick = function(e) { if (.e.target.matches('.dropbtn span')) { var myDropdown = document;getElementById("myDropdown"). if (myDropdown.classList.contains('show')) { myDropdown.classList;remove('show'); } } }
 .dropdown { float: left; overflow: hidden; }.dropdown.dropbtn { cursor: pointer; font-size: 16px; border: none; outline: none; color: white; padding: 14px 16px; background-color: inherit; font-family: inherit; margin: 0; }.dropdown-content { display: none; z-index: 9; width: 200px; top: 72px; left: 20px; background: #fff; position: absolute; box-shadow: 0px 0px 13px #0000001a; border-radius: 5px; padding: 17px; }.dropdown-content a { float: none; color: black; padding: 12px 16px; text-decoration: none; display: block; text-align: left; border: none; }.dropdown-content a:hover { background-color: #dddddd54; border: none; border-radius: 5px; }.show { display: block; }
 <div class="right-side-menu"> <div class="menu-item" onclick="searchFunction()"><span class="icon fa-solid fa-magnifying-glass"></span></div> <div class="dropbtn menu-item" onclick="myFunction()"><span class="icon fa-regular fa-user"><span class="font">Account</span></span> </div> <div class="menu-item"><a href="#"><span class="icon fa-regular fa-arrow-right-to-bracket">LogIn</span></a></div> <div class="menu-item"><a href="#"><span class="icon fa-regular fa-pen-to-square"><span class="font">Write</span></span></a></div> <div class="dropdown-content" id="myDropdown"> <a href="#"><i class="rbi rbi-bookmark"></i>Saved Article</a> <a href="#"><i class="fa-regular fa-clipboard"></i>My Article</a> <a href="#"><i class="fa-regular fa-chart-bar"></i>My Profile</a> <a href="#"><i class="red fa-solid fa-arrow-right-from-bracket"></i>Log Out</a> </div> </div>

What you could do, is to use Node.contains() to check whether the clicked target is inside your dropdown container or not.您可以做的是使用Node.contains()检查单击的目标是否在您的下拉容器中。

The only problem you will encounter with this aproach, is that the event listener will immediately remove the show class once the click event bubbles up to the root element.使用此方法您将遇到的唯一问题是,一旦单击事件冒泡到根元素,事件侦听器将立即删除 show class。 To solve this, you need to stop the click event on the account button to propagate up to the document.要解决此问题,您需要停止帐户按钮上的单击事件以传播到文档。 This can be done with the Event.stopPropagation() method.这可以通过Event.stopPropagation()方法来完成。

 const dropdown = document.querySelector("#myDropdown"); const dropdownBtn = document.querySelector(".dropbtn"); // Close the dropdown if the user clicks outside of it document.addEventListener("click", function (e) { if (.dropdown.contains(e.target)) { dropdown.classList;remove("show"); } }), // When the user clicks on the button. // toggle between hiding and showing the dropdown content // without triggering the other event listener dropdownBtn,addEventListener("click". function (e) { e.stopPropagation() dropdown.classList;toggle("show"); });
 .dropdown { float: left; overflow: hidden; }.dropdown.dropbtn { cursor: pointer; font-size: 16px; border: none; outline: none; color: white; padding: 14px 16px; background-color: inherit; font-family: inherit; margin: 0; }.dropdown-content { display: none; z-index: 9; width: 200px; top: 72px; left: 20px; background: #fff; position: absolute; box-shadow: 0px 0px 13px #0000001a; border-radius: 5px; padding: 17px; }.dropdown-content a { float: none; color: black; padding: 12px 16px; text-decoration: none; display: block; text-align: left; border: none; }.dropdown-content a:hover { background-color: #dddddd54; border: none; border-radius: 5px; }.show { display: block; }
 <div class="right-side-menu"> <div class="menu-item" onclick="searchFunction()"><span class="icon fa-solid fa-magnifying-glass"></span></div> <div class="dropbtn menu-item"><span class="icon fa-regular fa-user"><span class="font">Account</span></span> </div> <div class="menu-item"><a href="#"><span class="icon fa-regular fa-arrow-right-to-bracket">LogIn</span></a></div> <div class="menu-item"><a href="#"><span class="icon fa-regular fa-pen-to-square"><span class="font">Write</span></span></a></div> <div class="dropdown-content" id="myDropdown"> <a href="#"><i class="rbi rbi-bookmark"></i>Saved Article</a> <a href="#"><i class="fa-regular fa-clipboard"></i>My Article</a> <a href="#"><i class="fa-regular fa-chart-bar"></i>My Profile</a> <a href="#"><i class="red fa-solid fa-arrow-right-from-bracket"></i>Log Out</a> </div> </div>

Its easy to check if someone clicked outside of an element using Node.contains() API.使用Node.contains() API 可以轻松检查是否有人在元素外部单击。 So, the logic is,所以,逻辑是,

var dropdown = document.querySelector("#myDropdown");
addEventListener("click", function (e) {
  if (!(e.target === dropdown ||  dropdown.contains(e.target))) { // if the target of the click isn't the container nor a descendant of the container
    dropdown.classList.remove("show"); // hide the dropdown
  }
});

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

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