Home > Software design >  Click menu close outside of menu not working - buttonevent.matches if not a function
Click menu close outside of menu not working - buttonevent.matches if not a function

Time:05-27

The dropdown menu which is supposed to close when clicking outside of the menu button is not working. I have had this problem before but the problem re-occurred and can't get to a solution. Help would be appreciated. I am not sure as to why the code doesn't work, so some clarification would be helpful.

let btnn = document.getElementById("btn");
btnn.addEventListener('click', function() {
  let dropdown = document.getElementById('dropdown');
  dropdown.classList.toggle("visible");
})

window.onclick = function(event){
    if (!event.target.matches('#btn')) {
        let dropd = document.getElementById('dropdown');
        dropd.classList.remove("visible");
    } 
}
body {
    height: 100vh;
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

.logo {
    display: block;
    text-align: left;
    background: red;
    height: 10vh;
}

.logo #logo {
    display: inline;
    line-height: 10vh;
    font-size: 3em;
    margin-left: 0.8em;
    
}

button#btn {
    display: inline;
    float: right;
    margin-right: 2em;
    margin-top: 0;
    margin-bottom: 0;
    border: none;
    background-color: red;
    padding: 0;
}

nav {
    display: block;
    background-color: black;
    width: 100vw;
}

nav ul {
    display: none;
    list-style-type: none;
    margin: 0;
    padding-left: 0;
}

nav ul li {
    text-align: center; 
}

.link {
    display: block;
    color: white;
    font-size: 2.4em;
    background-color: blue;
    text-decoration: none;
    width: 100vw;
    height: 7vh;
    line-height: 7vh;
    border-bottom: 2px solid black;
    text-align: center;
}

.visible {
    display: block;
}

.fa-bars:before, .fa-navicon:before {
    content: "\f0c9";
    font-size: 50px;
    line-height: 10vh;
}

@media only screen and (min-width: 480px) { 
    
    .fa-bars:before, .fa-navicon:before {
        font-size: 35px;
    }

    /* #dropdown {
        display: block;
    } */

}
  
  @media only screen and (min-width: 600px) {

    .fa-bars:before, .fa-navicon:before {
        font-size: 30px;
    }
    
}
<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width">
    <!-- <meta http-equiv="content-type" content="text/html; charset=UTF-8" /> -->
    <script
  src="https://code.jquery.com/jquery-3.6.0.js"
  integrity="sha256-H K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk="
  crossorigin="anonymous"></script>
    <script src="https://kit.fontawesome.com/36947df53d.js" crossorigin="anonymous"></script>
    <link rel="stylesheet" type="text/css" href="style.css" />
  </head>
  <body>
  <div >
    <p id="logo">Logo</p>
    <button id="btn"><i ></i></button>
  </div>
   <nav>
     <ul id="dropdown">
       <li><a href="#" >Link 1</a></li>
       <li><a href="#" >Link 2</a></li>
       <li><a href="#" >Link 3</a></li>
     </ul>
   </nav>
    <script src="script.js"></script>
  </body>
</html>

CodePudding user response:

let me restructure your javascript better. It will solve your problem and the code is precise too I think.

document.querySelector("body").addEventListener("click", function(event){  
  let dropd = document.querySelector('#dropdown');
  if (!event.target.parentNode.matches('#btn')) {    
    dropd.classList.remove("visible");
  } else {
    dropd.classList.toggle("visible");
  }
});

In your previous code, I believe your button click was overridden by the window click. Here, I'm clicking on the body and simply matching the button id. If it matches, then I'm doing the toggle and otherwise, I'm removing the class.

*** I've used parentNode. If you're wondering why I'd used that you can just simply console log to see where the button click happens. You will see that the click is getting the icon inside the button. That is why I took the icon parent to check if the click is happening where I want it.

CodePudding user response:

You can use document.body.addEventListener('click', fn, true);. Your js file should be like this maybe

let btnn = document.getElementById("btn");
btnn.addEventListener('click', function() {
  let dropdown = document.getElementById('dropdown');
  dropdown.classList.toggle("visible");
})

document.body.addEventListener("click", () => {
    let dropd = document.getElementById('dropdown');
    dropd.classList.remove("visible");
}, true); 
  • Related