web-dev-qa-db-fra.com

Ajouter un effet de diapositive à bootstrap dropdown

J'utilise bootstrap , et j'aimerais ajouter une animation à une liste déroulante. Je veux y ajouter une animation, glisser vers le bas et revenir en arrière en la quittant. Comment pourrais-je faire ça?

Choses que j'ai essayées:

Changer le fichier déroulant Js comme ceci:

Comment puis-je faire en sorte que la liste déroulante de navigation de Bootstrap glisse de haut en bas?

77
Ben Beri

Si vous effectuez une mise à jour vers Bootstrap 3 (BS3), ils ont exposé de nombreux événements Javascript qui permettent de lier les fonctionnalités souhaitées. Dans BS3, ce code affiche tous vos menus déroulants. l'effet d'animation que vous recherchez:

  // Add slideDown animation to Bootstrap dropdown when expanding.
  $('.dropdown').on('show.bs.dropdown', function() {
    $(this).find('.dropdown-menu').first().stop(true, true).slideDown();
  });

  // Add slideUp animation to Bootstrap dropdown when collapsing.
  $('.dropdown').on('hide.bs.dropdown', function() {
    $(this).find('.dropdown-menu').first().stop(true, true).slideUp();
  });

Vous pouvez en savoir plus sur les événements BS3 ici et plus particulièrement sur les événements déroulants ici .

140
cogell

Il est également possible d'éviter d'utiliser JavaScript comme effet de liste déroulante et d'utiliser la transition CSS3 en ajoutant ce petit morceau de code à votre style:

.dropdown .dropdown-menu {
    -webkit-transition: all 0.3s;
    -moz-transition: all 0.3s;
    -ms-transition: all 0.3s;
    -o-transition: all 0.3s;
    transition: all 0.3s;

    max-height: 0;
    display: block;
    overflow: hidden;
    opacity: 0;
}

.dropdown.open .dropdown-menu { /* For Bootstrap 4, use .dropdown.show instead of .dropdown.open */
    max-height: 300px;
    opacity: 1;
}

Le seul problème avec cette méthode est que vous devez spécifier manuellement la hauteur maximale. Si vous définissez une très grande valeur, votre animation sera très rapide.

Cela fonctionne comme un charme si vous connaissez la hauteur approximative de vos listes déroulantes, sinon vous pouvez toujours utiliser javascript pour définir une valeur de hauteur maximale précise.

Voici un petit exemple: DEMO


! Il y a un petit bug avec padding dans cette solution, vérifiez le commentaire de Jacob Stamm avec la solution.

62
MadisonTrash

Je fais quelque chose comme ça mais en vol stationnaire au lieu de cliquer .. C'est le code que j'utilise, vous pourrez peut-être modifier un peu pour qu'il fonctionne correctement avec clic

$('.navbar .dropdown').hover(function() {
  $(this).find('.dropdown-menu').first().stop(true, true).delay(250).slideDown();
}, function() {
  $(this).find('.dropdown-menu').first().stop(true, true).delay(100).slideUp()
});
23
Yohn

Je ne sais pas si je peux heurter ce fil, mais j'ai trouvé une solution rapide au bogue visuel qui se produit lorsque la classe ouverte est supprimée trop rapidement. En gros, il suffit d'ajouter une fonction OnComplete dans l'événement slideUp et de réinitialiser toutes les classes et tous les attributs actifs. Va quelque chose comme ça:

Voici le résultat: exemple Bootply

Javascript/Jquery:

$(function(){
    // ADD SLIDEDOWN ANIMATION TO DROPDOWN //
    $('.dropdown').on('show.bs.dropdown', function(e){
        $(this).find('.dropdown-menu').first().stop(true, true).slideDown();
    });

    // ADD SLIDEUP ANIMATION TO DROPDOWN //
    $('.dropdown').on('hide.bs.dropdown', function(e){
        e.preventDefault();
        $(this).find('.dropdown-menu').first().stop(true, true).slideUp(400, function(){
            //On Complete, we reset all active dropdown classes and attributes
            //This fixes the visual bug associated with the open class being removed too fast
            $('.dropdown').removeClass('show');
            $('.dropdown-menu').removeClass('show');
            $('.dropdown').find('.dropdown-toggle').attr('aria-expanded','false');
        });
    });
});
15
IndieRok

voici ma solution pour les effets de diapositives et de fondus:

   // Add slideup & fadein animation to dropdown
   $('.dropdown').on('show.bs.dropdown', function(e){
      var $dropdown = $(this).find('.dropdown-menu');
      var orig_margin_top = parseInt($dropdown.css('margin-top'));
      $dropdown.css({'margin-top': (orig_margin_top + 10) + 'px', opacity: 0}).animate({'margin-top': orig_margin_top + 'px', opacity: 1}, 300, function(){
         $(this).css({'margin-top':''});
      });
   });
   // Add slidedown & fadeout animation to dropdown
   $('.dropdown').on('hide.bs.dropdown', function(e){
      var $dropdown = $(this).find('.dropdown-menu');
      var orig_margin_top = parseInt($dropdown.css('margin-top'));
      $dropdown.css({'margin-top': orig_margin_top + 'px', opacity: 1, display: 'block'}).animate({'margin-top': (orig_margin_top + 10) + 'px', opacity: 0}, 300, function(){
         $(this).css({'margin-top':'', display:''});
      });
   });
10
Vedmant

Au clic, cela peut être fait en utilisant le code ci-dessous

$('.dropdown-toggle').click(function() {
  $(this).next('.dropdown-menu').slideToggle(500);
});
8
Abhimanyu Rana

J'utilise le code ci-dessus mais j'ai changé l'effet de retard par slideToggle.

Il glisse la liste déroulante en survol avec animation.

$('.navbar .dropdown').hover(function() {
    $(this).find('.dropdown-menu').first().stop(true, true).slideToggle(400);
    }, function() {
    $(this).find('.dropdown-menu').first().stop(true, true).slideToggle(400)
    });
7
Augusto Triste

Mise à jour 2018 Bootstrap 4

Dans Boostrap 4, le .open la classe a été remplacée par .show. Je voulais implémenter cela en utilisant uniquement des transitions CSS sans avoir besoin de JS ou de jQuery supplémentaire ...

.show > .dropdown-menu {
  max-height: 900px;
  visibility: visible;
}

.dropdown-menu {
  display: block;
  max-height: 0;
  visibility: hidden;
  transition: all 0.5s ease-in-out;
  overflow: hidden;
}

Démo: https://www.codeply.com/go/3i8LzYVfMF

Remarque: max-height peut être défini sur n'importe quelle valeur suffisamment grande pour contenir le contenu du menu déroulant.

6
Zim

La réponse élargie était ma première réponse, alors excusez-moi s'il n'y avait pas assez de détails auparavant.

Pour Bootstrap 3.x, je préfère personnellement les animations CSS et j'utilise animate.css & avec les Bootstrap Javascript Hooks. Bien que cela ne produise peut-être pas exactement l'effet recherché, c'est une approche assez flexible.

Étape 1: Ajoutez animate.css à votre page avec les balises head:

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.4.0/animate.min.css">

Étape 2: Utilisez le code HTML Bootstrap standard sur le déclencheur:

<div class="dropdown">
  <button type="button" data-toggle="dropdown">Dropdown trigger</button>

  <ul class="dropdown-menu">
    ...
  </ul>
</div>

Étape 3: Ajoutez ensuite 2 attributs de données personnalisés à l'élément dropdrop-menu; data-dropdown-in pour l'animation in et data-dropdown-out pour l'animation out. Ceux-ci peuvent être n’importe quel effet animate.css comme fadeIn ou fadeOut

<ul class="dropdown-menu" data-dropdown-in="fadeIn" data-dropdown-out="fadeOut">
......
</ul>

Étape 4: Ajoutez ensuite le code Javascript suivant pour lire les attributs de données de type dropdown-in/out et réagir aux Bootstrap hooks de l'API Javascript./events ( http://getbootstrap.com/javascript/#dropdowns-events ):

var dropdownSelectors = $('.dropdown, .dropup');

// Custom function to read dropdown data
// =========================
function dropdownEffectData(target) {
  // @todo - page level global?
  var effectInDefault = null,
      effectOutDefault = null;
  var dropdown = $(target),
      dropdownMenu = $('.dropdown-menu', target);
  var parentUl = dropdown.parents('ul.nav'); 

  // If parent is ul.nav allow global effect settings
  if (parentUl.size() > 0) {
    effectInDefault = parentUl.data('dropdown-in') || null;
    effectOutDefault = parentUl.data('dropdown-out') || null;
  }

  return {
    target:       target,
    dropdown:     dropdown,
    dropdownMenu: dropdownMenu,
    effectIn:     dropdownMenu.data('dropdown-in') || effectInDefault,
    effectOut:    dropdownMenu.data('dropdown-out') || effectOutDefault,  
  };
}

// Custom function to start effect (in or out)
// =========================
function dropdownEffectStart(data, effectToStart) {
  if (effectToStart) {
    data.dropdown.addClass('dropdown-animating');
    data.dropdownMenu.addClass('animated');
    data.dropdownMenu.addClass(effectToStart);    
  }
}

// Custom function to read when animation is over
// =========================
function dropdownEffectEnd(data, callbackFunc) {
  var animationEnd = 'webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend';
  data.dropdown.one(animationEnd, function() {
    data.dropdown.removeClass('dropdown-animating');
    data.dropdownMenu.removeClass('animated');
    data.dropdownMenu.removeClass(data.effectIn);
    data.dropdownMenu.removeClass(data.effectOut);

    // Custom callback option, used to remove open class in out effect
    if(typeof callbackFunc == 'function'){
      callbackFunc();
    }
  });
}

// Bootstrap API hooks
// =========================
dropdownSelectors.on({
  "show.bs.dropdown": function () {
    // On show, start in effect
    var dropdown = dropdownEffectData(this);
    dropdownEffectStart(dropdown, dropdown.effectIn);
  },
  "shown.bs.dropdown": function () {
    // On shown, remove in effect once complete
    var dropdown = dropdownEffectData(this);
    if (dropdown.effectIn && dropdown.effectOut) {
      dropdownEffectEnd(dropdown, function() {}); 
    }
  },  
  "hide.bs.dropdown":  function(e) {
    // On hide, start out effect
    var dropdown = dropdownEffectData(this);
    if (dropdown.effectOut) {
      e.preventDefault();   
      dropdownEffectStart(dropdown, dropdown.effectOut);   
      dropdownEffectEnd(dropdown, function() {
        dropdown.dropdown.removeClass('open');
      }); 
    }    
  }, 
});

Étape 5 (facultatif): Si vous souhaitez accélérer ou modifier l'animation, vous pouvez le faire avec CSS comme suit:

.dropdown-menu.animated {
  /* Speed up animations */
  -webkit-animation-duration: 0.55s;
  animation-duration: 0.55s;
  -webkit-animation-timing-function: ease;
  animation-timing-function: ease;
}

A écrit un article avec plus de détails et un téléchargement si quelqu'un le souhaite: article: http://bootbites.com/tutorials/bootstrap-dropdown-effects-animatecss

J'espère que cela vous sera utile et que cette seconde rédaction a le niveau de détail dont Tom a besoin.

3
Tom James
$('.navbar .dropdown').hover(function() {
    $(this).find('.dropdown-menu').first().stop(true, true).slideDown();
}, function() {
    $(this).find('.dropdown-menu').first().stop(true, true).slideUp();
});

Ce code fonctionne si vous souhaitez afficher des listes déroulantes en survol.

Je viens de changer le .slideToggle à .slideDown & .slideUp et a supprimé le (400) timing

2
ChapDaddy65

référence de démarrage

Ajoutée parce que je continue de me faire prendre par la solution contenue dans ce fil et que ça m'emballe à chaque fois.

En gros, le menu déroulant BS supprime immédiatement le .open classe du parent, donc glisser ne fonctionne pas.

Utilisez le même bit que d'autres solutions pour slideDown ();

// ADD SLIDEUP ANIMATION TO DROPDOWN //
$('.dropdown').on('hide.bs.dropdown', function(e){
  e.preventDefault();
  $(this).find('.dropdown-menu').first().stop(true, true).slideUp(300, function(){
    $(this).parent().removeClass('open');
  });
});
1
Slipoch

Voici une solution simple et agréable utilisant jQuery qui fonctionne bien:

$('.dropdown-toggle').click(function () {
    $(this).next('.dropdown-menu').slideToggle(300);
});

$('.dropdown-toggle').focusout(function () {
    $(this).next('.dropdown-menu').slideUp(300);
})

La bascule d'animation de diapositive se produit en cliquant sur elle et glisse toujours vers le haut en perdant le focus.

Modifier le 300 valeur que vous voulez, plus le nombre est bas, plus l’animation est rapide.

Edit:

Cette solution ne fonctionnera que pour les vues de bureau. Des modifications supplémentaires seront nécessaires pour pouvoir afficher correctement le contenu sur mobile.

0
Barry Michael Doyle

Pour Bootstrap 3, cette variation des réponses ci-dessus rend l'animation mobile slideUp() _ plus lisse; les réponses ci-dessus ont une animation saccadée car Bootstrap supprime la classe .open du parent de la bascule immédiatement, donc ce code restaure la classe jusqu'à la fin de l'animation slideUp().

// Add animations to topnav dropdowns
// based on https://stackoverflow.com/a/19339162
// and https://stackoverflow.com/a/52231970

$('.dropdown')
  .on('show.bs.dropdown', function() {
    $(this).find('.dropdown-menu').first().stop(true, true).slideDown(300);
  })
  .on('hide.bs.dropdown', function() {
    $(this).find('.dropdown-menu').first().stop(true, false).slideUp(300, function() {
      $(this).parent().removeClass('open');
    });
  })
  .on('hidden.bs.dropdown', function() {
    $(this).addClass('open');
  });

Principales différences

  • Dans le gestionnaire d'événements hide.bs.dropdown, J'utilise la valeur par défaut de .stop() (false) pour son second argument (jumpToEnd).
  • Le gestionnaire d'événement hidden.bs.dropdown Restaure la classe .open Au parent de la bascule déroulante et le fait presque immédiatement après que la classe a été supprimée. Pendant ce temps, l'animation slideUp() est toujours en cours d'exécution et, comme dans les réponses ci-dessus, son rappel "the-animation-is-complete" est responsable de la suppression finale de la classe .open De son parent.
  • Les méthodes sont chaînées parce que le sélecteur de chaque gestionnaire d'événements est le même.
0
Jordan Bradford