views:

52

answers:

2

I'm am making a button that when clicked reveals a box with html inside. I'd like to hide that box if anything is clicked other than inside the same box. Any suggestion?

+3  A: 

You can use event propagation (bubbling) to your advantage here, for example:

$("#button").click(function(e) {
  //show #box
});
$("#button, #box").click(function(e) {
  e.stopPropagation();
});
$(document).click(function() {
  $("#box").hide();
});

You can test it out here, if clicking the button or inside the element (#box in this case), the event doesn't bubble. From anywhere else it doesn't bubble, up to document, which hides #box.

Nick Craver
I'm sure I could figure it out eventually but it's probably an easy thing for you. How would I implement this with #button using toggle instead of click?
Johnny Freeman
@Johnny - I think you'd still want `.click()` here with a `.toggle()` on the element (shows if hidden, hides if shown), like this: http://jsfiddle.net/nick_craver/zDhv5/10/
Nick Craver
I got this before I saw your comment, what do you think about this code as oppose to yours? $('#button').toggle(function(){ // show the box}, function() { // hide the box});$("#box").click(function() { e.stopPropagation();});$(document).click(function() { if($('#box').is(':visible')) { $("#button").trigger('click'); }});
Johnny Freeman
@Johnny - I would stick with the code in the last comment, for example what if you alternate clicks between the button and document it'll be in the wrong state...best to detect whether to close or not from the element itself.
Nick Craver
@Nick - Actually, that's why I put in the `.is(':visable')` statement. So, the code I made is working like it should but you clearly being more knowledgable on the subjuct, is there any reason I should or shouldn't do it this way? Check it out here: http://projects.pixelfuelmedia.com/ - Click on the search button (top right). By the way, thanks for your help. Really.
Johnny Freeman
@Johnny - Well it's one click handler on document vs a click handler *calling* a click handler, and also one click handler on the button vs 2 handlers alternating...so I guess I'd opt to keep it simpler all around but the original link in my comment....it also handles the case of something *else* showing or hiding the box, and works better in multiple-popup scenarios.
Nick Craver
@Nick - That's what I was looking for. Thanks for taking the time. It's guys like you that make the web a better place.
Johnny Freeman
@Johnny - welcome :), thanks for actually caring about the quality of your code, unfortunately it's an increasingly rare thing these days
Nick Craver
A: 
$(':not(#box)').bind('click', function() {
  // this should match everything except your box
});
Alec
Please do *not* do this, it'll bind a *ton* of event handlers and not solve the issue (any element *inside* `#box` will still close it.
Nick Craver
thought about doing this but like nick said it's not exactly what I'll be needing. Thanks for your suggestion!
Johnny Freeman
@Johnny - Be sure to recognize the immense inefficiency with this too, if you have 41,000 elements in your DOM, this will bind 40,999 event handlers...this is not the solution to **any issue**. Alec, I'm not sure you've thought through exactly what your code is doing, I'd rethink any approach mixing a global selector (implied here as `*:not()`) and binding.
Nick Craver