109881
109881

Reputation: 45

How to remove toggled class when clicking outside menu

The dropdown menu is designed with CSS and HTML/JS using a class called "is-open" that is added from JS. Once present inside the HTML div specified, it will activate the CSS to display the submenu.

However there is a small issue wherein the dropdown menu once clicked will not disappear unless the same menu item is clicked. (The class will not de-toggle when clicking outside the menu-content div)

As a basic functionality this menu needs to disappear once a user clicks not just on the menu, but anywhere on the page.

My present javascript is the following:

$(document).ready(function() {
   $(".has-submenu").click(function(e) {
      e.stopPropagation();
      if($(this).hasClass("is-open")) {
         $(this).removeClass("is-open");
      } else {
         $(".has-submenu").removeClass("is-open");
         $(this).addClass("is-open");
      }
   });
});

Here is a codepen example of the code: https://codepen.io/anon/pen/EwMjrz

Upvotes: 1

Views: 3070

Answers (2)

d0rf47
d0rf47

Reputation: 499

I want to add an additional answer that is simpler to implement and prevents any unwanted potential blocking behaviour by adding the click to the document.

  1. Add tabindex="-1" to the div which opens to show the menu when the is-open class is added
  2. When applying the is-open class to open and display the menu apply focus() to the element. This will allow for you to attach a blur event listener
  3. create the onblur event listener and simply remove the is-open class on blur and your menu will close whenever the click anywhere outside of the element.

This can prevent dom from intercepting click events why avoiding attaching the onclick event to the document or body as some other answers suggest. This answer here explains a bit more about the tabindex aspect which is how i figured out to use the focus and blur events: https://stackoverflow.com/a/46115264/12212051

<div class="sel" id="monthSelectDiv" aria-label="select month" tabindex="-1">
    <select id="monthSelect" name="monthSelect">
        <option disabled>Select Month</option>
        <option value="01"> January </option>                            
        <option value="02"> February </option>
    </select>
</div>

<script>
// Toggling the `.active` state on the `.sel`.
$('.sel').click(function () {
    $(this).toggleClass('active');
    $(this).focus();
});

$('.sel').blur(function () {
    $(this).removeClass('active');
});
</script>

Upvotes: 0

3Dos
3Dos

Reputation: 3487

You could add an event listener to the document to close your menu like so

$(document).ready(function() {
  $(".has-submenu").click(function(e) {
    e.stopPropagation();
    if($(this).hasClass("is-open")) {
      $(this).removeClass("is-open");
    } else {
      $(".has-submenu").removeClass("is-open");
      $(this).addClass("is-open");
    }
  });
  $(document).on('click', function (e) {
    e.stopPropagation();
    $('.has-submenu').removeClass("is-open");
  });
});

This should do the trick!

Upvotes: 3

Related Questions