web-dev-qa-db-fra.com

Arrêtez juste un menu déroulant de la fermeture au clic

J'ai un menu déroulant (un seul, pas tous), et à l'intérieur de celui-ci, je souhaite avoir plusieurs champs de saisie dans lesquels les utilisateurs peuvent saisir des éléments sans que le menu déroulant ne soit masqué dès que vous cliquez dessus (mais cela se ferme si vous cliquez en dehors de celui-ci).

J'ai créé un jsfiddle: http://jsfiddle.net/denislexic/8afrw/2/

Et voici le code, c'est basique:

<div class="btn-group" style="margin-left:20px;">
  <a class="btn dropdown-toggle" data-toggle="dropdown" href="#">
    Action
    <span class="caret"></span>
  </a>
  <ul class="dropdown-menu">
    <!-- dropdown menu links -->
      <li>Email<input type="text" place-holder="Type here" /></li>
      <li>Password<input type="text" place-holder="Type here" /></li>
  </ul>
</div>​

Donc, fondamentalement, je veux qu'il ne ferme pas en cliquant sur le menu déroulant (mais ferme en cliquant sur le bouton d'action ou en dehors du menu déroulant). Jusqu'à présent, ma meilleure hypothèse a été d'ajouter un cours et d'essayer de faire quelques exercices de synthèse, mais je ne pouvais pas le comprendre. 

Merci pour toute aide. 

46
denislexic

Le problème est que le plugin jQuery boostdown dropdown ferme le menu déposé lorsque vous cliquez n'importe où. Vous pouvez désactiver ce comportement en capturant les événements de clic sur votre élément de menu déroulant et en l'empêchant d'atteindre les écouteurs d'événements de clic sur l'élément body.

Il suffit d'ajouter

$('.dropdown-menu').click(function(event){
     event.stopPropagation();
 });​

jsfiddle peut être trouvé ici

110
CraigTeegarden

Je sais que cette question ne concerne pas Angular en soi, mais pour quiconque utilise Angular, vous pouvez passer l'événement depuis le code HTML et arrêter la propagation via $ event:

<div ng-click="$event.stopPropagation();">
    <span>Content example</span>
</div>
39
parliament

En fait, si vous étiez dans Angular.js, il serait plus élégant de faire une directive pour cela:

app.directive('stopClickPropagation', function() {
    return {
        restrict: 'A',
        link: function(scope, element) {
            element.click(function(e) {
                e.stopPropagation();
            });
        }
    };
});

Et puis, dans le menu déroulant, ajoutez la directive:

<div class="dropdown-menu" stop-click-propagation> 
    my dropdown content...
<div>

Surtout si vous souhaitez arrêter la propagation pour plusieurs événements de souris:

...
element.click(function(e) {
    e.stopPropagation();
});

element.mousedown(...
element.mouseup(...
...
5
Nahn

Une autre solution rapide, ajoute simplement l'attribut onclick à div ayant la classe dropdown-menu:

<div class="dropdown-menu" onClick="event.stopPropagation();">...</div>
5
Hassan Talha

Après avoir essayé beaucoup de techniques, j'ai trouvé que c'était la meilleure à utiliser, cela ne causait aucun inconvénient, ce qui est même simple:

$(document)
.on( 'click', '.dropdown-menu', function (e){
    e.stopPropagation();
});

Ce qui vous permet également de relier en direct des éléments internes dans des listes déroulantes.

1
Julian Xhokaxhiu

J'ai eu ce problème, mais dans un composant de réaction - le composant de réaction était dans un menu déroulant de démarrage avec un formulaire. Chaque fois qu'un élément de la liste déroulante était cliqué, il se fermait, ce qui posait des problèmes lors de la saisie d'un élément dans le formulaire.

Les fonctions habituelles e.preventDefault() et e.stopPropagation() ne fonctionneraient pas dans l'application de réaction car l'événement jQuery était déclenché immédiatement et réagissait en essayant d'intervenir par la suite.

Le code ci-dessous m'a permis de résoudre mon problème.

stopPropagation: function(e){
    e.nativeEvent.stopImmediatePropagation();
}

ou au format ES6

stopPropagation(e){
    e.nativeEvent.stopImmediatePropagation();
}

J'espère que cela peut être utile à quiconque se débat avec les autres réponses en essayant de l'utiliser en réaction.

0
Sprose

aussi, empêchez le clic sauf si vous cliquez sur un élément de bouton 

$('.dropdown-menu').click(function(e) {
    if (e.target.nodeName !== 'BUTTON') e.stopPropagation();
});
0
Elise Chant