简体   繁体   中英

Click outside div and close div, even if div is not a child of the parent

I have two div's that I open that kinda belong together, but for programming reasons can't be connected. I simplified the code here because it's a lot of code. This is the basic.

<div id="container">

  <div id="div1">
     <div> when I am clicked I will open div2 </div>
  </div>

  <div id="div2">
     <div> I can be clicked and all the div's stay open </div>
  </div>

</div> 

And this is the connected JavaScript

  $(document).mouseup(function (e) {
    var container = $("#div1");
    if (!container.is(e.target) && container.has(e.target).length === 0) {
      container.hide();
    }
  });

  $(document).mouseup(function (e) {
    var container = $("#div2");
    if (!container.is(e.target) && container.has(e.target).length === 0) {
      container.hide();
    }
  });

Now what I would like to do is when I click outside div1 it should close div1 .

When I click on div1 it opens div2 .

Currently with the above when I click in div2 it closes div1 , because it is not a child of div1 . So it should keep div2 opened.

And when I click outside div1 or div2 it should close the two div's.

How can I combine the two JavaScript codes to get the explained behaviour?

Summary of what I try to accomplish:

  1. Click on the div inside div1 will open div2
  2. Click outside div1 or div2 will close both div1 and div2 .
  3. In case the div inside div1 is not clicked and one clicks outside div1 , it should close div1 .

Pretty theorical....

But requirements are quite clear. I would do it using .stopPropagation() .

e.target is the element clicked. If it is a child of an element having a "concurring handler" on the same event, the handler from the parent will execute. Except if you stop the propagation , which you should look at here .

Having a handler on a top-most parent that say "hide all", will will overcome the handler of the child saying somthing else. So in this case... From the child, you do not want the click (or mouseup... or whatever the event) to propagate to the top parent.

In short : .stopPropagation() will keep the event on the releveant element and you can "not care about" any concurring handler from the parents.

 $("#div1").on("click", function(e){ e.stopPropagation(); whoAmI(e); $("#div2").show(); }); $("#div2").on("click", function(e){ e.stopPropagation(); whoAmI(e); console.log("I was clicked and #div1 stayed opened."); }); $("#container").on("click",function(e){ $("#div1,#div2").hide(); whoAmI(e); }); function whoAmI(e){ console.clear(); console.log( "I'm "+e.target.tagName+" "+((e.target.id=='')? "child" : e.target.id) ); } 
 #container{ height:1000px; } #div1, #div2{ border:1px solid red; padding:2em; margin:3em; } #div2{ display:none; } #container>div>div{ border:1px solid blue; padding:0.5em; margin:1em; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="container"> <div id="div1"> <div> When I am clicked I will open div2 </div> <div> I also do the same. </div> </div> <div id="div2"> <div> I can be clicked and all the div's stay open </div> <div> I also do the same. </div> <div> And me too! </div> </div> </div> 

Using closest() and a common class makes this simpler

 $(document).mouseup(function(e) { !$(e.target).closest('.content').length && $('.content').hide(); }); $('#div1').click(function() { $('#div2').show(); }) 
 #div2{display:none} 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="container"> <div id="div1" class="content"> <div> when i am clicked i will open div2 </div> </div> <div id="div2" class="content"> <div> i can be clicked and all the div's stay open </div> </div> </div> 

I suggest this the code written with jQuery:

$(document).on('click', function (e) {
    if ( e.currentTarget.id == 'div1' ) {
        $("#div2").show();
    } else if ( e.currentTarget.id == 'div2' ) {
        $("#div1").hide();
    } else {
        $("#div1").hide();
        $("#div2").hide();
    }
    return false;
});

or in plain Javascript:

function handleClicks(e) {
    var first = document.getElementById('div1'),
        second = document.getElementById('div2');
    if ( e.currentTarget.id == 'div1' ) {
        second.style.display = 'block';
    } else if ( e.currentTarget.id == 'div2' ) {
        first.style.display = 'none';
    } else {
        first.style.display = 'none';
        second.style.display = 'none';
    }
}
document.body.addEventListener('click', handleClicks, false);

Also check the if-else statements there.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM