简体   繁体   中英

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.

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. 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.

 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. 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
  }
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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