2012-08-24 21 views
62

estoy usando bootstrap, y me gustaría añadir animación a un menú desplegable.Añadir un efecto de diapositivas para arrancar desplegable

Quiero añadir una animación a ella, deslice hacia abajo y una copia de seguridad al salir de ella.

¿Cómo podría hacer esto?

cosas que intenté:

Cambio de los Js desplegable archivo de la siguiente manera:

How can I make Bootstrap's navigation dropdown slide smoothly up and down?

Cualquier ayuda sería bueno! ¡gracias!.

+1

¿incluyó el bootstrap-dropdown.js en alguna parte? No lo veo en el encabezado ... y awwww estos pasteles. ¡Tengo tanta hambre ahora! – ablm

+0

Hmm está dentro de boostrap.js, lo incluí pero no funcionó, así que lo eliminé pero lo volví a agregar y sí, si eliminé el mini, no funcionará en absoluto – Jony

+0

EDITAR: oh sí, está incluido. – ablm

Respuesta

119

Si actualiza para arrancar 3 (BS3), se han expuesto muchos de los eventos de JavaScript que son agradables a atar su funcionalidad deseada en. En BS3, este código dará todas sus menús desplegables el efecto de animación que busca:

// 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(); 
    }); 

Usted puede leer acerca de los eventos BS3 here y específicamente acerca de los eventos desplegables here.

+4

Tengo un problema con la parte de este. Mientras está en modo colapsado (Chrome), el ancho del menú desplegable vuelve al ancho como si se viera en pantalla completa. Mientras usa FF, se desliza hacia abajo, pero se esconde en lugar de deslizarse hacia arriba. – ScubaSteve

+3

Yo también veo este problema, de hecho creé otro hilo preguntando específicamente sobre él ... http://stackoverflow.com/questions/26267207/bootstrap-3-dropdown-slidedown-strange-behavior-when-navbar-collapsed pero yo no sé exactamente cómo arreglarlo. Siento que la clase Dropdown no está esperando que termine la transición antes de procesar el evento 'hidden.bs.dropdown'. –

+2

esto funciona y hace lo que deseo, pero en la ventana gráfica móvil, la lista desplegable para submenús desaparece rápidamente y se ve entrecortada, ¡aunque gracias por compartir! –

19

que estoy haciendo algo por el estilo, pero en lugar de flotar en tecleo .. este es el código que estoy usando, usted podría ser capaz de modificarlo un poco para conseguir que funcione en tecleo

$('.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() 
}); 
7

el clic se puede hacer mediante el siguiente código

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

Esto funciona bien, pero cuando pierde el foco, el menú desplegable permanece abierto, lo que no es normal. –

7

estoy usando el código anterior, pero me han cambiado el efecto de retardo por slideToggle.

Desliza el menú desplegable al desplazarse con la animación.

$('.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) 
    }); 
+1

realmente no necesita definirlo dos veces. cuando se usa un interruptor, funcionará sin el segundo. – smerny

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

Este código funciona si desea mostrar las listas desplegables en vuelo estacionario.

acabo de cambiar el .slideToggle-.slideDown & .slideUp, y se retira el (400) tiempo

10

aquí está mi solución para la diapositiva efecto de desvanecimiento &:

// 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:''}); 
     }); 
    }); 
+0

Gracias. Tu código funciona perfectamente. Sin embargo, no entiendo muy bien por qué necesitamos tener '$ (esto).css ({'margen superior': ''}); '@Vedmant – DucCuong

+0

Esto es para eliminar el parámetro de margen superior después de la animación, en caso de que los menús desplegables tengan algunos márgenes agregados en estilos personalizados (como en mi tema). para trabajar sin él, ya que anima a orig_margin_top, pero es más claro no dejar estilos en línea adicionales una vez completada la animación. – Vedmant

15

No sé si puedo subir esto hilo, pero descubrí una solución rápida para el error visual que ocurre cuando la clase abierta se elimina demasiado rápido. Básicamente, todo lo que hay que hacer es agregar una función OnComplete dentro del evento slideUp y restablecer todas las clases y atributos activos.Es algo como esto:

aquí está el resultado: Bootply example

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('open'); 
      $('.dropdown').find('.dropdown-toggle').attr('aria-expanded','false'); 
     }); 
    }); 
}); 
+0

La demostración tiene un menú bloqueado abierto después de hacer clic en unos pocos en una fila. – SventoryMang

+0

@DOTang Sí, supongo que no fue perfecto, de ahí la solución rápida, creo que un poco de refactorización lo haría mejor. Esperemos que para cuando Bootstrap4 salga, lo habrán arreglado – IndieRok

+0

La única solución que funciona para móviles – vgulkevic

50

También es posible evitar el uso de JavaScript para el efecto desplegable, y el uso de transición CSS3, añadiendo esta pequeña pieza de código a su estilo:

.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 { 
    max-height: 300px; 
    opacity: 1; 
} 

El único problema con esta forma es que se debe especificar manualmente max-height. Si establece un valor muy grande, su animación será muy rápida.

Funciona como un amuleto si conoce la altura aproximada de sus menús desplegables, de lo contrario todavía puede usar javascript para establecer un valor preciso de altura máxima.

Aquí es pequeño ejemplo: DEMO


! Hay un pequeño error con el relleno en esta solución, verifique el comentario de Jacob Stamm con la solución.

+2

Buena solución, lo aprecio. –

+0

Sí, gracias por esto. Se sentía como un dios enviado! – cwiggo

+0

Esta respuesta debe ser aceptada. – WhiteHorse

3

Respuesta expandida, fue mi primera respuesta, así que disculpe si no había suficientes detalles antes.

Para Bootstrap 3.x Personalmente prefiero las animaciones de CSS y he estado usando animate.css & junto con los enganches de Dropdown Javascript de Bootstrap. Aunque podría no tener exactamente el efecto que busca, es un enfoque bastante flexible.

Paso 1: Añadir animate.css a su página con las etiquetas de la cabeza:

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

Paso 2: Uso el estándar HTML Bootstrap en el gatillo:

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

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

Paso 3: Luego agregue 2 atributos de datos personalizados al elemento dropdrop-menu; datos desplegables para la animación y la lista desplegable de datos para la animación de salida. Estos pueden ser animados.CSS efectos como fadeIn o fadeOut

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

Paso 4: A continuación añadimos el siguiente JavaScript para leer los datos-desplegable en atributos de datos de entrada/salida y reaccionar a los Bootstrap Javascript API ganchos/eventos (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'); 
     }); 
    }  
    }, 
}); 

Paso 5 (opcional): Si desea acelerar o alterar la animación puede hacerlo con CSS como la siguiente:

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

escribió un artículo con más detalle y una descarga si anyones interesados: artículo: http://bootbites.com/tutorials/bootstrap-dropdown-effects-animatecss

la esperanza de que es útil & esta escritura segundo hasta tiene el nivel de detalle que se necesita Tom

+2

Sería bueno, al menos, incluir algunos detalles en su respuesta, simplemente el enlace a su sitio no es realmente una buena respuesta. – ajshort

+0

@GeraldSchneider actualizó la respuesta con más detalles. Fue mi primera respuesta en stackoverflow, así que agradezco los comentarios. –

0

Aquí es un buen solución sencilla utilizando jQuery que funciona muy bien:

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

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

la diapositiva de animación de palanca se produce al hacer clic y siempre se desliza b ack up en perder el foco.

Altere el valor 300 a cualquier cosa que desee, cuanto menor sea el número, más rápida será la animación.

Editar:

Esta solución sólo funciona para las vistas de escritorio. Necesitará algunas modificaciones adicionales para mostrarse bien para dispositivos móviles.

+0

Esto funciona para mí, pero después de mover el mouse al submenú (es decir, lejos de 'desplegable-alternar') desaparece de nuevo, lo que significa que no puedo seleccionar los elementos del submenú – Bassie

Cuestiones relacionadas