简体   繁体   中英

How to close dropdown menu when user clicks

I am working on navigation with a clickable dropdown menu. The dropdown uses an input tag. Where I'm getting stuck is that I need the dropdown to close if the visitor clicks somewhere else on the page. I'm trying to use a target property, matches() method, and an onclick event.

What I notice in the console is that when I open the dropdown, both conditional statements appear and the dropdown doesn't open. It's as though the dropdown opens and closes at the same time.

What am I doing wrong and how do I get this to function correctly so that a user can simply open the dropdown menu and have it close when they click somewhere else on the webpage?

Thanks in advance. Below is the code: Here is the codepen: https://codepen.io/bfoley650/pen/NWxeXRB?editors=1111

HTML

<div class="dropdown">
    <input id="checkId" type="checkbox" name="menu" />
    <label for="checkId">
         <span class="heyhey">⋮</span>
    </label> 
    <div class="dropdown-content">
      <ul class="heyheyhey">
      <li><a href="#">Item 1</a></li>
      <li><a href="#">Item 2</a></li>
      <li><a href="#">Item 3</a></li>
        <li><a href="#">Item 4</a></li>
 
      </ul>
    </div>  
</div>

CSS

span {
  color: black;
  font-size: 24px;
  margin: 0 15px;
}

li {
  list-style-type: none;
}

.dropdown {
  float: left;
  overflow: hidden;
  font-size: 17px;
  border: none; 
  outline: none; 
  color: white;
  background-color: inherit;
  font-family: inherit; 
  margin: 10px 0; 
}
 
.dropdown-content {
  display: none;
  position: absolute;
  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 20px 12px 0;
  text-decoration: none;
  display: block;
  text-align: left;
}

input {
  display: none;
}

label {
  position: relative;
  cursor: pointer;
}


input:checked~.dropdown-content {
  display: block;
}

JS

let el = document.querySelector(".dropdown-content"); 

window.onclick = function(e) {
      if (e.target.matches(".heyhey")) {
        console.log("You clicked the dropdown menu");
      } else {
        console.log("You clicked somewhere else");
        el.style.display = "none";
      }
    } 

The code:

window.onclick = function(e) {
    if (e.target.matches(".heyhey")) {
        console.log("You clicked the dropdown menu");
        el.style.display = "block"; // Shows the element
        e.preventDefault(); // Prevents propagation
    } else {
        console.log("You clicked somewhere else");
        el.style.display = "none";
    }
}

.preventDefault

event.preventDefault stops propagation, JS by default calls onclick for parent elements, this stops the double counting of your onclick handler.

el.style.display = "block";

This changes the display style from none, thus showing the element. This could be changed to any other display style except none .

I think you should move the span above the label:

<span class="heyhey">⋮</span>
<label for="checkId">
    <input id="checkId" type="checkbox" name="menu" />
</label> 

and add the following code to your conditional:

console.log("You clicked the dropdown menu");
el.style.display = "block";

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