25

I'm trying to make it so that my dropdown menu shows when you click a button, and hides when you click anywhere except the dropdown menu.

I have some code working, as far as not closing when you click the menu, however when you click the document when the menu is closed, it shows the menu, so it continuously toggles no matter where you click.

$(document).click(function(event) {
    if ($(event.target).parents().index($('.notification-container')) == -1) {
        if ($('.notification-container').is(":visible")) {
            $('.notification-container').animate({
                "margin-top": "-15px"
            }, 75, function() {
                $(this).fadeOut(75)
            });
        } else {
            //This should only show when you click: ".notification-button" not document
            $('.notification-container').show().animate({
                "margin-top": "0px"
            }, 75);
        }
    }
});
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Dylan Cross
  • 5,918
  • 22
  • 77
  • 118
  • To describe your code; It binds the click event to the entire `document` and when that event is triggered it checks if the target(clicked) element has any parents with the class ".notification-container" and if it does it checks if any element with that class is visible. If so, it hides(animates) all elements with the class ".notification-container" and otherwise it shows(animates) them instead. – Stefan Jan 10 '12 at 11:39
  • The best solution out there is [stackoverflow.com/questions/152975/how-to-detect-a-click-outside-an-element][1]. [1]: http://stackoverflow.com/questions/152975/how-to-detect-a-click-outside-an-element – lightofsouls Jun 28 '13 at 08:31
  • hey man, would you mind accepting an answer? :) – epoch May 06 '16 at 07:08

8 Answers8

35

jQuery's closest() function can be used to see if the click is not within the menu:

$('body').click(function(e) {
    if ($(e.target).closest('.notification-container').length === 0) {
        // close/animate your div
    }
});
epoch
  • 16,396
  • 4
  • 43
  • 71
  • I haven't been able to get this to work as expected, it does the same thing as it does with my current code – Dylan Cross Jan 10 '12 at 08:59
  • This is simple and works well. You may want to consider adding the click event to html instead of body in case your page does not fill the full height of the viewport – Charlie Martin Feb 28 '14 at 19:14
  • Would this still work if a particular child handler stopped propagation though? If a user has code anywhere in their website that stops propagation, (be it from a library or legacy code) wouldn't it affect this solution? – AlexMorley-Finch Jan 20 '15 at 16:46
7

you can do something like this if your item is not clicked then hide its dropping list in case of drop down

$(':not(#country)').click(function() {
     $('#countrylist').hide();
});
James Donnelly
  • 126,410
  • 34
  • 208
  • 218
Bipin Chandra Tripathi
  • 2,550
  • 4
  • 28
  • 45
5

I am using a very simple code for this as :-

$(document).click(function(e){

   if($(e.target).closest('#dropdownID').length != 0) return false;
   $('#dropdownID').hide();
});

Hope it will useful.

Thanks!!

4

I usually do like this:

$('.drop-down').click(function () {
    // The code to open the dropdown

    $('body').click(function () {
        // The code to close the dropdown
    });
});

So put your body (elsewhere) click function inside the drop-down open click function.

2

Try this :

// The code to close the dropdown
$(document).click(function() {
    ...
});

// The code to open the dropdown 
$(".drop-down").click(function() {
    ...
    return false;
});
Samuel Caillerie
  • 8,259
  • 1
  • 27
  • 33
Mandeep Pasbola
  • 2,631
  • 2
  • 26
  • 50
2

This might not be a complete solution but I´ve created a demo to help you out. Let me know it´s not working as you´d expect.

$(document).click(function(e) {

    var isModalBox = (e.target.className == 'modal-box');

    if (!isModalBox) {
        $('.modal-box:visible').animate({
            "margin-top": "-15px"
        }, 75, function() {
            $(this).fadeOut(75);
        });
    }
});

$('a').click(function(e) {
    e.stopPropagation(); // Important if you´d like other links to work as usual.
});

$('#temp-button').click(function(e) {
    e.preventDefault();
    $('.modal-box').show().animate({
        "margin-top": "0px"
    }, 75);
});
Stefan
  • 5,644
  • 4
  • 24
  • 31
  • That seems to work as it should in your fiddle demo, thanks. But I found a plugin that works perfectly, with less code, I'm going to post it as my answer. – Dylan Cross Jan 10 '12 at 20:39
1

try something like:

$(document).click(function(event) { 

if($(event.target).parents().index($('.notification-container')) == -1) {
    if($('.notification-container').is(":visible")) {
        $('.notification-container').animate({"margin-top":"-15px"}, 75, function({$(this).fadeOut(75)});
    }   
}        
});

$(".notification-button").click(function(event){
    event.stopPropagation();
    $('.notification-container').show().animate({"margin-top":"0px"}, 75);
});
redmoon7777
  • 4,498
  • 1
  • 24
  • 26
  • strange. if you could post the relevant parts of your code at http://jsfiddle.net/ it would be much easier to figure this out – redmoon7777 Jan 10 '12 at 09:31
1

This is what I've decided to use, it's a nice little jQuery plugin that works with little code.

Here's the plugin: http://benalman.com/projects/jquery-outside-events-plugin/

This is the code that makes my above code in my question work.

$(document).ready(function(){
    $(".notification-button").click(function(){
        $('.notification-container').toggle().animate({"margin-top":"0px"}, 75); 
    }); 

    $('.notification-wrapper').bind('clickoutside', function (event) {
        $('.notification-container').animate({"margin-top":"-15px"}, 75, function(){$(this).fadeOut(75)});
    });
});
Dylan Cross
  • 5,918
  • 22
  • 77
  • 118