2

My document click function isn't hiding my menu when I click the document outside of my menu. When I click the img it shows the menu and when I click the img again it hides it but when I document click I want it to hide the menu does any one know what I'm doing wrong and how to make it work.

var visible = false;
var id = $(this).attr('id');

$(document).not('#' + id + ' div:eq(1)').click(function () {
    if (visible) {            
        $('.dropdownlist .menu').hide();
        visible = false;
    }
});    


$(this).find('div:eq(1)').click(function (e) {
     var menu = $(this).parent().find('.menu');

     if (!visible) {
         menu.show();
         visible = true;
     } else if (visible) {
         menu.hide();
         visible = false;
     }
     menu.css({ 'left': $(this).position().left + $(this).width() - menu.find('ul').width(), 
                'top': $(this).position().top + $(this).height() });
 })
Jasper
  • 75,717
  • 14
  • 151
  • 146
ONYX
  • 5,679
  • 15
  • 83
  • 146

2 Answers2

2

I had a similar problem and solved it with the following code:

$("body").mouseup(function(){ 
    if (visible) {
        $('.dropdownlist .menu').hide();
         visible = false;
    }
});

instead of your $(document).not(.. code.

nickdos
  • 8,348
  • 5
  • 30
  • 47
  • Instead of a bool indicating whether a context menu is visible, use a reference to the context menu object. Use it as above but it also tells you *which* menu needs hiding, which is super handy when there are several context menus. This doesn't interfere with click events on the menu items. – Peter Wone Aug 06 '13 at 02:47
2
//add event.stopPropagation() when the user clicks on a .menu element
$('.menu').on('click', function (event) {

    //.stopPropagation() will stop the event from bubbling up to the document
    event.stopPropagation();
});

//add the click event handler to the image that will open/close .menu elements
$('img').on('click', function (event) {

    //we call .stopPropagation() again here so the document won't receive this event
    event.stopPropagation();

    //cache .menu element
    var $div = $('.menu');

    //this if statement determines if the .menu should be shown or hidden, in my example I'm animating its top property
    if ($div.css('top') == '-50px') {
        $div.stop().animate({top : 0}, 250);
    } else {
        $div.stop().animate({top : '-50px'}, 150);
    }
});

//add click event handler to the document to close the .menu
$(document).on('click', function () {
    $('div').stop().animate({top : '-50px'}, 150);
});

jsfiddle: http://jsfiddle.net/jasper/n5C9w/1/

Jasper
  • 75,717
  • 14
  • 151
  • 146
  • Interesting solution, very instructive. Personally I use a global variable contextMenu which contains a reference to the active contextMenu wrapped in a jquery object, because this not only tells me a context menu needs hiding, it tells me *which* menu. – Peter Wone Aug 06 '13 at 02:44