简体   繁体   中英

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

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!

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>

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