Make menu disappear when you click outside!

I made this tutorial of menu but made the menu smaller and I have been trying to make it disappear when I click outside it not when I click on it and it never work. how I can do that? help, please.

menu tutorial:

<html>
<head>

<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css"
  integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
  crossorigin=""/>

<script src="https://unpkg.com/[email protected]/dist/leaflet.js"
integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="
crossorigin=""></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>

<title></title>
</head>
<body>
  <button id="roundButton" ></button>

  <div  id="flyoutMenu" >

        <div class="panel-heading">
          <h3 class="panel-title">Complaint</h3>
          <div class="pull-right">
            <!-- <span class="clickable filter" data-toggle="tooltip" title="Toggle table filter" data-container="body"> -->
              <i class="glyphicon glyphicon-filter"></i>
            </span>
          </div>
        </div>
        <div class="panel-body">
          <input type="text" class="form-control" id="dev-table-filter" data-action="filter" data-filters="#dev-table" placeholder="Filter Developers" />
        </div>
        <table class="table table-hover table table-bordered table-striped mb-0" id="dev-table">
          <thead>
            <tr>
              <th>ID</th>
              <th>Date</th>
              <th>Category</th>
              <th>Status</th>
            </tr>
          </thead>
          <tbody>
            <?php
            $servername = "localhost";
            $username = "root";
            $password = "";
            $dbname = "muqu";
            $conn = new mysqli($servername, $username, $password, $dbname);
            if ($conn->connect_error) {
              die("Connection failed: " . $conn->connect_error);
            }
            $qury = mysqli_query($conn,"select complaintId ,date,category,status,description,roomNum from complaint");
             $romNumerquery = mysqli_query($conn,"select roomNumber from classroom");
             //$result = $conn->query($sql);
             if ($qury-> num_rows >0){
               while ($row = $qury-> fetch_assoc()) {
                 echo "<tr><td>".$row["complaintId"]."</td>"."<td>".$row["date"]."</td>"."<td>".$row["category"]."</td>"."<td>".$row["status"]."</td></tr>";
               }
               echo "</tbody>";

             }
             else {

               echo "no result";
             }
             $conn->close();
             ?>

          </tbody>
        </table>
      </div>
  </div>

  <script>
  var roundButton = document.querySelector("#roundButton")
  var flyoutMenu = document.querySelector("#flyoutMenu")

  roundButton.addEventListener("click", showMenu, false);
  flyoutMenu.addEventListener("click", hidMenu, false);

  function showMenu(e){
    flyoutMenu.classList.add("show");
    document.body.style.overflow="hidden";
  }
  function hidMenu(e){
    flyoutMenu.classList.remove("show");
    document.body.style.overflow="auto";
  }
  </script>


<style media="screen">
body {
background-color: #EEE;
font-family: Helvetica, Arial, sans-serif;
padding: 25px;
margin: 0;
overflow: auto;
}

#container li {
margin-bottom: 10px;
}

#roundButton {
background-color: #96D9FF;
margin-bottom: 20px;
width: 50px;
height: 50px;
border-radius: 50%;
border: 10px solid #0065A6;
outline: none;
transition: transform .3s cubic-bezier(0, .52, 0, 1);

}

#roundButton:hover {
background-color: #96D9FF;
cursor: pointer;
border-color: #003557;
transform: scale(1.2, 1.2);
}

#roundButton:active {
border-color: #003557;
background-color: #FFF;
}
#flyoutMenu {
width: 50vw;
height: 45vh;
background-color: #FFF;
position: fixed;
top: 0;
left: 0;
transform: translate3d(-50vw, 0, 0);
transition: transform .3s cubic-bezier(0, .52, 0, 1);
/* overflow: scroll; */
z-index: 1000;

}
#flyoutMenu.show{
transform: translate3d(0vw,0,0)
}

#flyoutMenu h2 a {
color: #333;
margin-left: 15px;
text-decoration: none;
}
#flyoutMenu h2 a:hover {
text-decoration: underline;
}
</style>
</document>

</body>

</html>

Hi @rhfproject221 - that is a great question! One way you can solve this is by taking advantage of how events travel and “hiding” the click event selectively. Here is the modified code that accomplishes what you are trying to do:

var roundButton = document.querySelector("#roundButton")
var flyoutMenu = document.querySelector("#flyoutMenu")

document.body.addEventListener("click", clickedHere, false);
flyoutMenu.addEventListener("click", menuClicked, true);

var menuOpen = false;

roundButton.addEventListener("click", showMenu, false);
flyoutMenu.addEventListener("click", hidMenu, false);

function showMenu(e){
  flyoutMenu.classList.add("show");
  document.body.style.overflow="hidden";
  menuOpen = true;

  e.stopPropagation();
}
function hidMenu(e){
  flyoutMenu.classList.remove("show");
  document.body.style.overflow="auto";

  menuOpen = false;
}

function menuClicked(e) {
  console.log("Menu clicked");

  e.stopPropagation();
}

function clickedHere(e) {
  if (menuOpen) {
    hidMenu();
  }
  console.log("Body clicked");
}

There are a few things to call out. First, here is the behavior that we want:

  1. When I click anywhere inside my menu, the menu shouldn’t disappear
  2. When I click anywhere outside of my menu, the menu should disappear (if it is open)

From this point, for #2 we need to listen for an event click outside of the menu. The body element is a good place for that. For #1, we want to detect a click inside the menu. Note that the event listener registration has the bubbling property set to true. This ensures that clicking on the menu will cause the menu element to overhear the click first BEFORE sending it over to the body element.

To avoid the body element from overhearing the click, the stopPropagation call solves that.

There are a few more details there, but what I summarized are the big ones. Does this help?

Cheers,
Kirupa

1 Like