Question

I have the following code:

(function ($) {
    $(document).ready(function () {
        $(".clicker_class").click(function () {
            $('.show_menu_users').show();
        });
    });
})(jQuery);

$('.clicker_class').click(function (e) {
    e.stopPropagation();
});

I am new to JQuery and a bit puzzled. I was easily able to use the show function but I need to use the close or hide function to close the menu when the user clicks on .clicker_class again and when the user clicks away at something else. I tried using the e.stopPropogation(); but didn't work. How do I do that given my above code?

Update:

I got it to close if a user clicks elsewhere using this:

$(document).mouseup(function (e)
{
    var container = $(".clicker_class");

    if (container.has(e.target).length === 0)
    {
         $(".show_menu_users").hide();
    }
});

Question:

Now I just need the menu to close when the user clicks on .clicker_class. How can i do that now?

Was it helpful?

Solution 2

UPDATED to close menu if clicked outside of clicker_class elements.

You can track the state of the show_menu_users using a boolean. When you click on the clicker_class elements, toggle the menu and update the boolean. When you click elsewhere in teh document, close the menu.

(function ($) {
    $(document).ready(function () {
        var isShowing = false;

        var toggleMenu = function() {
            isShowing = !isShowing; //change boolean to reflect state change
            $('.show_menu_users').toggle(isShowing); //show or hide element
        }

        $(document).on('click', function (e) {
            if($(e.target).is('.clicker_class') || $(".clicker_class").has(e.target).length !== 0) {
                toggleMenu();
            } else {
                isShowing = false;
                $('.show_menu_users').hide();  
            }
        });
    });
})(jQuery);

Working example here.

OTHER TIPS

Cfs's solution works but there is an easier way to do that, without basing yourself on a global variable (which is better to avoid).

The ".toggle()" function (without parameters) of jQuery hide your element if it is visible and show it if it isn't. Then you just have to launch $( ".show_menu_users" ).toggle() when you click on the button and hide the menu when you click on the document. The problem is that clicking on any elements will close the menu, to prevent it you just have to stop the event propagation by using "event.stopPropagation()"

$( document ).ready( function () {
    $( ".clicker_class" ).on( "click", function ( event ) {
        event.stopPropagation(); 

       $( ".show_menu_users" ).toggle(); 
    });

    $( document ).on( "click", function () {
        $( ".show_menu_users" ).hide(); 
    }); 

    $( ".show_menu_users" ).on( "click", function ( event ) {
        event.stopPropagation(); 
    }); 
}); 

Working example here

See if its fit your needs:

$(function(){
    //we set a tabindex attribute in case of this element doesn't support natively focus
    //outline just for styling
    $(".clicker_class").prop('tabindex',-1).css({outline:0});
});

$(".clicker_class").click(function () {
     $('.show_menu_users').toggle();
}).on('focusout',function(){
    $(this).hide();
});

I use this method, which I think is a cleaner answer.

Add to your html page just after/before the opening/closing body tag:

<div class="main-mask"></div>

Then in your js file:

(function() {

  'use strict';

  $(".sidenav-toggle").on( "click", function() {
      $("#sidenav").toggleClass("sidenav--open");
      $(".main-mask").toggleClass("main-mask-visible");
  });

  $(".main-mask").on( "click", function() {
      $("#sidenav").toggleClass("sidenav--open");
      $(".main-mask").toggleClass("main-mask-visible");
  });

})();

In your css:

.main-mask {
    height: 100%;
    left: 0;
    opacity: 0.1;
    top: 0;
    visibility: hidden;
    width: 100%;
    z-index: 1;
    position: fixed;
}

This way, your mask acts as the click away. You can bind/unbind events and use the .main-mask class with other elements. The downside is that it needs to be added to the page. You could use css body:after {content:''} to remove that dependency.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top