web-dev-qa-db-fra.com

jquery menu déroulant fermant en cliquant à l'extérieur

Je développe un simple menu déroulant avec jQuery. Lorsqu'un utilisateur appuie sur une zone de déclenchement, il fait basculer la zone de liste déroulante. Ma question est de savoir comment avoir un événement de clic en dehors du menu déroulant pour qu'il ferme le menu déroulant.

55
user670800

Vous pouvez indiquer à chaque clic que les bulles remontent dans le DOM pour masquer la liste déroulante, et si vous cliquez pour que le parent de la liste déroulante arrête de bouillonner.

/* Anything that gets to the document
   will hide the dropdown */
$(document).click(function(){
  $("#dropdown").hide();
});

/* Clicks within the dropdown won't make
   it past the dropdown itself */
$("#dropdown").click(function(e){
  e.stopPropagation();
});

Démo: http://jsbin.com/umubad/2/edit

111
Sampson

comment avoir un événement de clic en dehors du menu déroulant pour qu'il ferme le menu déroulant? Heres le code

$(document).click(function (e) {
    e.stopPropagation();
    var container = $(".dropDown");

    //check if the clicked area is dropDown or not
    if (container.has(e.target).length === 0) {
        $('.subMenu').hide();
    }
})
28
Pash

Vous devez associer votre événement click à un élément. S'il y a beaucoup d'autres éléments sur la page, vous ne voudriez pas associer un événement de clic à tous.

Une solution potentielle consiste à créer une division transparente en dessous de votre menu déroulant, mais au-dessus de tous les autres éléments de la page. Vous voudriez le montrer quand le menu déroulant a été montré. Attribuez à l'élément un clic-clic qui masque la liste déroulante et la div transparente.

$('#clickCatcher').click(function () { 
  $('#dropContainer').hide();
  $(this).hide();
});
#dropContainer { z-index: 101; ... }
#clickCatcher { position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 100; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="dropDown"></div>
<div id="clickCatcher"></div>
12
jacob.toye

Arrêter la propagation d’événements dans certains éléments peut devenir dangereux car cela pourrait empêcher l’exécution de certains scripts. Vérifiez donc si le déclenchement provient de la zone exclue de l'intérieur de la fonction.

$(document).on('click', function(event) {
  if (!$(event.target).closest('#menucontainer').length) {
    // Hide the menus.
  }
});

Ici, la fonction est lancée lorsque vous cliquez sur le document, mais exclut le déclenchement de #menucontainer. Pour plus de détails https://css-tricks.com/dangers-stopping-event-propagation/

10
Jithin B

La réponse sélectionnée ne fonctionne que pour un menu déroulant. Pour solution multiple serait:

$('body').click(function(event){
   $dropdowns.not($dropdowns.has(event.target)).hide();
});
5
Maciej Pyszyński

Un autre exemple de liste déroulante multiple qui fonctionne https://jsfiddle.net/vgjddv6u/

$('.moderate .button').on('click', (event) => {
  $(event.target).siblings('.dropdown')
    .toggleClass('is-open');
});

$(document).click(function(e) {
  $('.moderate')
    .not($('.moderate').has($(e.target)))
    .children('.dropdown')
    .removeClass('is-open');
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.4.0/css/bulma.css" rel="stylesheet" />

<script
  src="https://code.jquery.com/jquery-3.2.1.min.js"
  integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
  crossorigin="anonymous"></script>

<style>
.dropdown {
  box-shadow: 0 0 2px #777;
  display: none;
  left: 0;
  position: absolute;
  padding: 2px;
  z-index: 10;
}

.dropdown a {
  font-size: 12px;
  padding: 4px;
}

.dropdown.is-open {
  display: block;
}
</style>


<div class="control moderate">
  <button class="button is-small" type="button">
        moderate
      </button>

  <div class="box dropdown">
    <ul>
      <li><a class="nav-item">edit</a></li>
      <li><a class="nav-item">delete</a></li>
      <li><a class="nav-item">block user</a>   </li>
    </ul>
  </div>
</div>


<div class="control moderate">
  <button class="button is-small" type="button">
        moderate
      </button>

  <div class="box dropdown">
    <ul>
      <li><a class="nav-item">edit</a></li>
      <li><a class="nav-item">delete</a></li>
      <li><a class="nav-item">block user</a></li>
    </ul>
  </div>
</div>
4
Y. Özdemir