jQuery drop down menu closing by clicking outside

JavascriptJqueryDrop Down-Menu

Javascript Problem Overview


I am developing a simple dropdown menu with jQuery . When a user press on a trigger area, it will toggle the dropdown area. My question is how to have a click event outside of the dropdown menu so that it close the dropdown menu ?

Javascript Solutions


Solution 1 - Javascript

You can tell any click that bubbles all the way up the DOM to hide the dropdown, and any click that makes it to the parent of the dropdown to stop bubbling.

/* Anything that gets to the document
   will hide the dropdown */
$(document).click(function(){
  $("#dropdown").hide();
});

/* Clicks within the dropdown won't make
   it past the dropdown itself */
$("#dropdown").click(function(e){
  e.stopPropagation();
});

Demo: http://jsbin.com/umubad/2/edit

Solution 2 - Javascript

how to have a click event outside of the dropdown menu so that it close the dropdown menu ? Heres the code

$(document).click(function (e) {
    e.stopPropagation();
    var container = $(".dropDown");

    //check if the clicked area is dropDown or not
    if (container.has(e.target).length === 0) {
        $('.subMenu').hide();
    }
})

Solution 3 - Javascript

Stopping Event Propagation in some particular elements ma y become dangerous as it may prevent other some scripts from running. So check whether the triggering is from the excluded area from inside the function.

$(document).on('click', function(event) {
  if (!$(event.target).closest('#menucontainer').length) {
    // Hide the menus.
  }
});

Here function is initiated when clicking on document, but it excludes triggering from #menucontainer. For details https://css-tricks.com/dangers-stopping-event-propagation/

Solution 4 - Javascript

You would need to attach your click event to some element. If there are lots of other elements on the page you would not want to attach a click event to all of them.

One potential way would be to create a transparent div below your dropdown menu but above all other elements on the page. You would show it when the drop down was shown. Have the element have a click hander that hides the drop down and the transparent div.

$('#clickCatcher').click(function () { 
  $('#dropContainer').hide();
  $(this).hide();
});

#dropContainer { z-index: 101; ... }
#clickCatcher { position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 100; }

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="dropDown"></div>
<div id="clickCatcher"></div>

Solution 5 - Javascript

Another multiple dropdown example that works https://jsfiddle.net/vgjddv6u/

$('.moderate .button').on('click', (event) => {
  $(event.target).siblings('.dropdown')
    .toggleClass('is-open');
});

$(document).click(function(e) {
  $('.moderate')
    .not($('.moderate').has($(e.target)))
    .children('.dropdown')
    .removeClass('is-open');
});

<link href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.4.0/css/bulma.css" rel="stylesheet" />

<script
  src="https://code.jquery.com/jquery-3.2.1.min.js"
  integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
  crossorigin="anonymous"></script>

<style>
.dropdown {
  box-shadow: 0 0 2px #777;
  display: none;
  left: 0;
  position: absolute;
  padding: 2px;
  z-index: 10;
}

.dropdown a {
  font-size: 12px;
  padding: 4px;
}

.dropdown.is-open {
  display: block;
}
</style>


<div class="control moderate">
  <button class="button is-small" type="button">
        moderate
      </button>

  <div class="box dropdown">
    <ul>
      <li><a class="nav-item">edit</a></li>
      <li><a class="nav-item">delete</a></li>
      <li><a class="nav-item">block user</a>   </li>
    </ul>
  </div>
</div>


<div class="control moderate">
  <button class="button is-small" type="button">
        moderate
      </button>

  <div class="box dropdown">
    <ul>
      <li><a class="nav-item">edit</a></li>
      <li><a class="nav-item">delete</a></li>
      <li><a class="nav-item">block user</a></li>
    </ul>
  </div>
</div>

Solution 6 - Javascript

Selected answer works for one drop down menu only. For multiple solution would be:

$('body').click(function(event){
   $dropdowns.not($dropdowns.has(event.target)).hide();
});

Solution 7 - Javascript

There is a tricky way to do this. You can manipulate blur event by adding tabIndex.

$('.click').click(function (e) {
    $(this).siblings('.dropdown').fadeToggle(100);
});

$('.container').blur(function (e) { 
    $('.dropdown').fadeOut(100);
});

.container{
  position: relative;
  display: inline-block;
}

.click{
  cursor: pointer;
  user-select: none;
  z-index: 1;
}

.dropdown{
  position: absolute;
  left: 0;
  top: 100%;
  display: none;
  background: #eee;
  padding: 1rem;
  z-index: 2;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="container" tabIndex="1">
  <section class="click">click this</section>
  <section class="dropdown">
    dropdown menu here
  </section>
</section>

<br /> <br />

<section class="container" tabIndex="2">
  <section class="click">click this</section>
  <section class="dropdown">
    dropdown menu here
  </section>
</section>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser670800View Question on Stackoverflow
Solution 1 - JavascriptSampsonView Answer on Stackoverflow
Solution 2 - JavascriptPashView Answer on Stackoverflow
Solution 3 - JavascriptSyntax ErrorView Answer on Stackoverflow
Solution 4 - Javascriptjacob.toyeView Answer on Stackoverflow
Solution 5 - JavascriptY. ÖzdemirView Answer on Stackoverflow
Solution 6 - JavascriptMaciej PyszyńskiView Answer on Stackoverflow
Solution 7 - JavascriptMustafa AHCIView Answer on Stackoverflow