views:

2368

answers:

11

I have a floating div that gets displayed, and I want it to be hidden when the user clicks off the div. This would be similar to the .hover() funtion callback when hovering off an element. Only I want to do this for click.

I tried just setting a click event for the body, which would hide the div, but that gave unexpected results.

Anyone have ideas on how I could easily do this?

A: 
$('#divName').click(function(){
   $(this).toggle();
})
Aziz
This requires the user to click inside the div to trigger the toggle function. The question asks for it to hide when the user clicks anything but the shown div.
idrumgood
and how will you show it again? it means that you'll lose your div
Aziz
+17  A: 

If you want to clear the div when you click somewhere else in the page, you can do something like:

$('body').click(function(event) {
    if (!$(event.target).closest('#myDiv').length) {
        $('#myDiv').hide();
    };
});
DavidB
A: 

You're going to need to monitor the mouseDown event for the whole page, but you'll have to take note when the user is clicking inside your floating div.

I would suggest adding a hover event to your floated div so when the user is hovering over it, mouseDown is disregarded, but when it is not being hovered over mouseDown would close it

idrumgood
+1  A: 

Another, possibly simpler, option would be to add a transparent div between the floating DIV and the rest of the page.

A simple click event on the transparent DIV could handle the hiding, and it would avoid the issues you are encountering with the click event.

PhillFox
Great idea. I had done something like this in the past for a different situation. Thanks for bringing this one to my attention.
Nic Hubbard
Your welcome, and thanks for accepting the answer. I almost didn't post because I don't really know what you are designing and thought that the option may not work - but sometimes an outsiders perspective is the best way to solve a problem. Good luck!
PhillFox
How is this simpler than DavidB's answer?
JPot
Yeh, this seems like the harder solution...
J-P
I called it a simpler solution because Nic was reporting unexpected results when using the click event on the body. My solution may not be as elegant as DavidB's, I'm not as proficient at JQuery, but it would get the job done by simply waiting for a click event on the hidden DIV. I was just throwing out another option for him to consider...
PhillFox
A: 

Surely you're looking for the blur event?

annakata
*sigh* anyone want to explain the downvote at all? (or all these downvotes?)
annakata
The `blur` event only works for form elements, the asker was probably looking for something similar for non-form elements.
Tobias Baaz
well that's not true *at all* - http://www.quirksmode.org/dom/events/blurfocus.html
annakata
A: 

Here's a full-fledged event-driven approach

  • Custom events handle the "summoning" and "dismissing" of the layer as to not step on the toes of other click-based events
  • document.body listens to for a dismiss event only when the layer in question is actually visible

Zee code:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"&gt;
<html lang="en">
<head>
<title>test</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js"&gt;&lt;/script&gt;
<script type="text/javascript">

$(function()
{
  var $layer = $('#layer');
  var $body  = $('html');

  $layer
    .bind( 'summon', function( e )
    {
      $layer.show();
      $body.bind( 'click', dismissLayer );
    } )
    .bind( 'dismiss', function( e )
    {
      $layer.hide();
      $body.unbind( 'click', dismissLayer );
    } )
    .click( function( e )
    {
      e.stopPropagation();
    })
    .trigger( 'dismiss' )
  ;

  function dismissLayer( e )
  {
    $layer.trigger( 'dismiss' );
  }

  // This is optional - this just triggers the div to 'visible'
  $('#control').click( function( e )
  {
    var $layer = $('#layer:hidden');
    if ( $layer.length )
    {
      $layer.trigger( 'summon' );
      e.stopPropagation();
    }
  } );
});

</script>

<style type="text/css">
#layer {
  position: absolute;
  left: 100px;
  top: 20px;
  background-color: red;
  padding: 10px;
  color: white;
}
#control {
  cursor: pointer;
}
</style>

</head>
<body>

<div id="layer">test</div>
<span id="control">Show div</span>

</body>
</html>

It's a lot of code I know, but here just to show a different approach.

Peter Bailey
A: 

You can try this. http://benalman.com/projects/jquery-clickoutside-plugin/

rado
A: 

If you're using Jquery, you could use a selector like:

$("*:not(#myDiv)").live("click", function(){
    $("#myDiv").hide();
});
Kelly
Sorry - should be the following:$("*:not(#myTrigger)").live("click", function(){ $("#myDiv").hide();});
Kelly
Who voted that down and why? That worked perfectly for me. Thx!
j-man86
A: 

Using an event handler on the document works well for me:

function popUp( element )
{
    element.onmousedown = function (event) { event.stopPropagation(); };
    document.onmousedown = function () { popDown( element ); };

    document.body.appendChild( element );
}

function popDown( element )
{
    document.body.removeChild( element );

    document.onmousedown = null;
}
Gali
A: