18

I have a dropdown menu inside a DIV.

I want the dropdown to be hide when user click anywhere else.

$('div').blur(function() { $(this).hide(); }

is not working.

I know .blur works only with <a> but in this case what is the simplest solution?

Anders
  • 7,431
  • 6
  • 42
  • 76
Aamir Afridi
  • 6,095
  • 3
  • 38
  • 41

6 Answers6

21

Try using tabindex attribute on your div, see:

Check this post for more information and demo.

Amar Palsapure
  • 9,262
  • 1
  • 25
  • 46
comenk
  • 69
  • 2
  • 10
  • For this to work the div needs to be focused first. So make sure it is focused before trying to click outside div to see the affect – Bren Nov 25 '14 at 12:55
  • OMG ...GENIUS!! thanks so much...here i was trying to find a way to make a custom event handler... :) – carinlynchin Apr 18 '16 at 17:48
16

I think the issue is that divs don't fire the onfocusout event. You'll need to capture click events on the body and then work out if the target was then menu div. If it wasn't, then the user has clicked elsewhere and the div needs to be hidden.

<head>
  <script>
  $(document).ready(function(){
    $("body").click(function(e) {
      if(e.target.id !== 'menu'){
        $("#menu").hide();
      }      
    });
  });
  </script>
  <style>#menu { display: none; }</style>
</head>

<body>
  <div id="menu_button" onclick="$('#menu').show();">Menu....</div>
  <div id="menu"> <!-- Menu options here --> </div>

  <p>Other stuff</p>
</body>
wersimmon
  • 2,762
  • 2
  • 20
  • 33
David Henderson
  • 1,195
  • 1
  • 10
  • 16
  • 1
    I don't think this answers the question. My understanding is that aamir wants to hide the div when you click inside, unless you click the select element. – ScottE Aug 11 '09 at 11:36
  • This is wrong. What happens when the user clicks on another div which is not part of the menu? – rahul Aug 11 '09 at 11:40
  • 20
    A div can accept focus and issue onfocus and onblur if you specify a tabindex for it. Try this: `
    Blah
    `
    – vit Aug 11 '09 at 11:53
  • 1
    "This is wrong. What happens when the user clicks on another div which is not part of the menu?" Yes, thats true, it was just a simple example to demonstrate capturing events on the body and determining the actual element that was clicked. When properly implemented, you'd want to check other properties of the target (most likely the id) to ensure you were not clicking on the menu again. – David Henderson Aug 11 '09 at 13:40
  • Whilst this works, for a more comprehensive solution, particularly if your popup layer contains a number of nested elements, all of which might get the click event, check this answer: http://stackoverflow.com/a/4629849/1371408 – Matty J Aug 15 '14 at 02:23
5
$("body").click(function (evt) {
     var target = evt.target;
     if(target.id !== 'menuContainer'){
            $(".menu").hide();
    }                
});

give the div an id, for instance "menuContainer". then you can check by target.id instead of target.tagName to make sure its that specific div.

PulledBull
  • 967
  • 1
  • 9
  • 18
1

Not the cleanest way, but instead of capturing every click event on the page you could add an empty link to your div and use it as a "focus proxy" for the div.

So your markup will change to:

<div><a id="focus_proxy" href="#"></a></div>

and your Javascript code should hook to the blur event on the link:

$('div > #focus_proxy').blur(function() { $('div').hide() })

Don't forget to set the focus on the link when you show the div:

$('div > #focus_proxy').focus()
guyk
  • 113
  • 5
-1

I just encountered this problem. I guess none of the above can fix the problem properly, so I post my answer here. It's a combination of some of the above answers: at least it fixed 2 problems that one might met by just check if the clicked point is the same "id"

$("body").click(function(e) {
    var x = e.target;

    //check if the clicked point is the trigger
    if($(x).attr("class") == "floatLink"){
        $(".menu").show();
    } 
    //check if the clicked point is the children of the div you want to show 
    else if($(x).closest(".menu").length <= 0){
       $(".menu").hide();
    }
});
nhahtdh
  • 52,949
  • 15
  • 113
  • 149
-3

.click will work just fine inside the div tag. Just make sure you're not over top of the select element.

$('div').click(function(e) {
    var $target = $(e.target);
    if (!$target.is("select")) { $(this).hide() };
});
ScottE
  • 21,027
  • 18
  • 91
  • 129