1

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

AJF
  • 11,767
  • 2
  • 37
  • 64
109881
  • 45
  • 1
  • 6
  • [Hier is a good example with javascript only](https://codepen.io/Ferhad/pen/OxZWNm) – ferhado Oct 21 '17 at 10:27
  • @FerhadOthman Your solution does not work. It allows the first menu item (in this case, "Articles") to collapse when clicking outside the div, however any subsequent menu items are not affected. See https://codepen.io/hioioasd90/pen/qPwBEW – 109881 Oct 21 '17 at 10:40
  • the line 13 `var element = document.querySelector(".has-submenu.is-open");` the selector must be class is-open – ferhado Oct 21 '17 at 10:55

2 Answers2

3

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!

3Dos
  • 3,210
  • 3
  • 24
  • 37
  • I have added your revised code to the codepen https://codepen.io/anon/pen/EwMjrz however it is still not working. – 109881 Oct 21 '17 at 10:32
  • 1
    I'm going to assume you haven't actually tested your solution since your selector is incorrect and this only works when clicking within **WebsitePrimaryNav**'s `div` section and not elsewhere on the page. – NewToJS Oct 21 '17 at 10:33
  • Sorry, I edited my post which had a typo. I tested it on the codepen provided by @109881 (add the dot before has-submenu in the line) – 3Dos Oct 21 '17 at 10:36
  • @3Dos Now the selector is correct this still doesn't work unless you click within **WebsitePrimaryNav**'s `header` section. This will work when adding content but if the content does not fill the screen it will only be within the margin of page content that will activate the body click function. – NewToJS Oct 21 '17 at 10:37
  • @NewToJS : fixed it in a last edit. Sorry, I'm not used to jQuery. – 3Dos Oct 21 '17 at 10:42
0

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>
d0rf47
  • 409
  • 8
  • 20