1

I'm trying to make a Div that is initially hidden to show up and stay toggled unless i do one of the following events (so in that case they hide again):

  • reclick on the same element that displayed the div on the first hand
  • click outside the div (container)
  • click outside of a div's children (descendant of the container)

This is the code i come up with : (#menu_login being the menu on which i click to make the div appear and .bubble being the div in question)

$(document).ready(function(){
 
$(".bubble").hide();
$("#menu_login").click(function(){
$(".bubble").toggle();
});
$(document).mouseup(function (e)
{
    var container = $(".bubble");

    if (!container.is(e.target) // if the target of the click isn't the container...
        && container.has(e.target).length === 0) // ... nor a descendant of the container
    {
        container.hide();
    }
});

So first, the hide_on_load function works well, but the toggle and mouseup function seems to be in a conflict when running together.

They work well when i use only one of them (and i really like this mouseup function because of the way it allows me to click on the container's descendants even when outside of the div).

The thing happening is when i click on the menu and toggle the div, if i click it again to untoggle and hide the div my mouseup function creates a conflict : It looks like because i on the menu again to untoggle and hide the div again, the mouseup function also detects that i clicked outside of my div and hide my div before my toggle function can. So what happen is that the toggle function won't detect that i clicked the menu to untoggle and hide the div, but that i clicked to toggle and show the div because the mouseup function closed it 0.01sec before.

So i don't really know how to do to have theses two functions working together, i had some kind of idea about adding an exeption that says to the mouseup function not to hide the div if i click on the menu (the same it doesnt close it if i click on a div's descendant) so my toggle function can do it and there is no conflict, but my knowledges in JQuery are non-existent.

exemple :

$(document).mouseup(function (e)
{
    var container = $(".bubble");

    if (!container.is(e.target)  container...
        && container.has(e.target).length === 0)
        // and here : "don't close it if i click on my #menu_login neither
    {
        container.hide();
    }

Any help/suggestion is welcome, sorry if this a bit heavy to read but i tried to be as specific as possible.

Thank you !

-Apatik

apatik
  • 383
  • 4
  • 17

1 Answers1

1

There are three parts you have to consider:

  1. The toggling action you see when #menu_login is clicked (you have addressed this already). But what's more important is that we want to make sure the click event from this element does not bubble up to the document object, for which we will listen for click as well. This is done by using event.stopPropagation().
  2. To prevent clicks within the .bubble element from bubbling up, you will have to prevent the event from propagating when originating from it, too.
  3. Listen to click event bubbling up to the document. Since we used event.stopPropagation() on the anchor element, click events will not bubble from it, but will from the rest of the document (i.e. other elements). We conditionally hide the .bubble element if it is visible, by using .filter().

$(function(){
  $('.bubble')
  .hide()
  .click(function(event) {
    // Stops click event from bubbling to document (point #2)
    event.stopPropagation();
  });
  $('#menu_login').click(function(event){
    // Stops click event from bubbling to document (point #1)
    event.stopPropagation();
    
    // Toggle visibility (point #1)
    $('.bubble').toggle();
  });
  $(document).click(function() {
    // Hide bubble if visible (point #3)
    // Will listen to click events from all other elements
    // ... except for `#menu_login` because we have
    // ... prevent the click event from bubbling up
    $('.bubble').filter(':visible').hide();
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a id="menu_login" href="#">Menu login</a><div class="bubble">Bubble</div>
Terry
  • 63,248
  • 15
  • 96
  • 118
  • Thanks a lot for your answer, unfortunately the div fades away as soon as i try to click inside the div (the div contains a login form). Also i don't quite well understanf the stopPropagation as you tried to explain, would you care elaborating a bit more ? thanks again tho ! edit: i am also going to edit my post with the script you gave me, so you can check if i didnt messed up somewhere, maybe a balise or smth – apatik Oct 06 '15 at 21:34
  • If you want to avoid clicking within the bubble to cause the bubble itself to close, you will also have to stop the click event from bubbling when originating from the element itself, i.e. `$('.bubble').click(function(event) { event.stopPropagation; });`. I have updated my answer to address this issue. You can read more about event propagation here: http://stackoverflow.com/questions/4616694/what-is-event-bubbling-and-capturing – Terry Oct 06 '15 at 21:36
  • Allright it worked. Thanks a lot for the help, i'm definitely checking your link aswell because i'm really missing a point with this even propagation – apatik Oct 06 '15 at 21:51