How to close a dropdown if the user clicks another page location?

Asked

Viewed 1,488 times

4

What is the best method to hide a div, that is fulfilling the role of dropdown, when the user clicks on another page location?

At first, I value solutions cross-browser and without the use of frameworks, but any extra content of applications using jQuery or even CSS will be welcomed.

4 answers

7


A variation of Talles response, without jQuery, to IE9+ and other modern browsers:

document.addEventListener('mouseup', function(e) {
  var aEsconder = document.querySelector('[seu seletor]');
  var alvoDescendeDoAEsconder = (function(){
    var el = e.target.parentNode;
    while(el) {
      if(el === aEsconder) return true;
      el = el.parentNode;
    }
    return false;
  }());
  if (aEsconder !== e.target && !alvoDescendeDoAEsconder) 
    aEsconder.style.display = 'none';
});

4

$(document).mouseup(function (e) {
  var aEsconder = $('[seu seletor]');
  if (!aEsconder.is(e.target) && aEsconder.has(e.target).length == 0) aEsconder.hide();
});

(source)


Testing:

<!doctype html>
<html>
<head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
    <script>
        $(document).mouseup(function (e) {
            var aEsconder = $("#conteudo1");
            if (!aEsconder.is(e.target) && aEsconder.has(e.target).length == 0) aEsconder.hide();
        });
    </script>
</head>    
<body>
    <div>
        <div id="conteudo1" style="min-height: 100px; background-color: yellow;">Se clicado aqui essa div continua sendo exibida</div>
        <div id="conteudo2" style="min-height: 100px; background-color: red;">Se clicado aqui, ou em outro lugar da página, a div acima sumirá</div>
    </div>
</body>    
</html>

2

Since your Drop-down will close if the user clicks anywhere on the page, you can use a generic selector to close it, just by adding this code:

    $('*').click(function(e){
         e.stopPropagation();
         if(!$(this).hasClass('.classeDoElementorAbrir')){
           $('#suaDiv').hide();
         } 
    });

and for it to open:

$('btAbrir').click(function(e){
     e.stopPropagation();
     $('#suaDiv').show();
});
  • The selector $('*') will match all elements. If you have 1000 elements on the page, it will rotate $('#suaDiv').hide() 1000 times - this not counting the spread of the event, actually will run much more...

  • You were wrong, the question the guy asks a solution to close the drop-down when the user clicks on some element, so it will only run if the user clicks on some element of the screen, precisely why I used the function .click()...

  • True, I was wrong, it won’t run 1000 times in this case. But consider only the propagation part of the event: if you click a nested div 10 levels into the body, the event will propagate and run 10 times. Also, with this code a click inside the dropdown itself (for example, click the dropdown open arrow) will cause the closure. Note: I’m not the one who voted you down.

  • Solving your remarks I edited my answer, in the case of if for the element that has to open the drop-down there are millions of ways to treat this...

  • Okay, but you meant classeDoElementorFechar? I still prefer the solution with a single Event Handler and delegation ($('*').click adds an Handler to each html element).

  • It depends on the point of view, well, I did not present my answer claiming to be the best, I did what I would do at first, thankfully that the OS is very democratic and allows the owner of the question to choose the answer that suits you best is not even! ;)

  • Yes, no doubt! I was just trying to help, sorry if I seemed aggressive.

Show 2 more comments

0

  • 2

    Try to explain/show the solution in the answer itself (instead of just posting the fiddle)

  • Agree, loses the usability of the OS...

  • 2

    Your solution is very good, it would be nice if you simplified and detailed your answer. :)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.