我正在使用bootstrap,我想在下拉菜单中添加动画。我想向其中添加动画,滑出时将其上下滑动。我该怎么办?
我尝试过的事情:
像这样更改Js下拉文件:
Answers:
如果您更新到Bootstrap 3(BS3),它们会暴露很多Java事件,可以很好地将所需的功能绑定到其中。在BS3中,此代码将为所有下拉菜单提供所需的动画效果:
// 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();
});
hidden.bs.dropdown
事件之前没有等待转换完成。
通过向您的样式添加以下这段代码,也可以避免使用JavaScript产生下拉效果,而使用CSS3过渡:
.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;
}
这种方式的唯一问题是您应该手动指定max-height。如果您设置一个很大的值,您的动画将很快。
如果您知道下拉菜单的大致高度,它的作用就像一个魅力,否则您仍然可以使用JavaScript设置精确的最大高度值。
这是一个小例子:DEMO
!在此解决方案中存在一个带有填充的小错误,请在解决方案中检查Jacob Stamm的评论。
pointer-events:none
到折叠后的版本中,然后将其添加point-events: all
到菜单中.show
我正在执行类似的操作,但是将鼠标悬停而不是单击。.这是我正在使用的代码,您可能可以对其进行一些调整以使其在单击时起作用
$('.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()
});
<script>
标签下添加了此标签,但未发生任何事情
我不知道我是否可以碰到这个线程,但是我想出了一个快速修复开放类被快速移除时发生的视觉错误的方法。基本上,要做的就是在slideUp事件内添加OnComplete函数并重置所有活动的类和属性。像这样:
结果如下: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');
});
});
});
这是我的滑动和淡入淡出效果的解决方案:
// 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:''});
});
});
$(this).css({'margin-top':''});
@Vedmant
更新2018年Bootstrap 4
在Boostrap 4中,.open
该类已替换为.show
。我想仅使用CSS过渡来实现此功能,而无需额外的JS或jQuery ...
.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;
}
演示: https //www.codeply.com/go/3i8LzYVfMF
注意:max-height
可以将其设置为足以容纳下拉内容的任何大值。
margin-top
。
点击时,可以使用以下代码完成
$('.dropdown-toggle').click(function() {
$(this).next('.dropdown-menu').slideToggle(500);
});
我正在使用上面的代码,但已通过slideToggle更改了延迟效果。
它将鼠标悬停在带有动画的下拉列表上。
$('.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)
});
扩展答案,这是我的第一个答案,如果以前没有足够的详细信息,那么请原谅。
对于Bootstrap 3.x,我个人更喜欢CSS动画,并且我一直在使用animate.css&和Bootstrap Dropdown Javascript Hooks。尽管它可能并不完全具有您想要的效果,但是它是一种非常灵活的方法。
第1步:使用head标签将animate.css添加到您的页面:
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.4.0/animate.min.css">
步骤2:在触发器上使用标准的Bootstrap HTML:
<div class="dropdown">
<button type="button" data-toggle="dropdown">Dropdown trigger</button>
<ul class="dropdown-menu">
...
</ul>
</div>
步骤3:然后向dropdrop-menu元素添加2个自定义数据属性;输入动画的数据下拉输入和输出动画的数据下拉输出。这些可以是任何animate.css效果,例如fadeIn或fadeOut
<ul class="dropdown-menu" data-dropdown-in="fadeIn" data-dropdown-out="fadeOut">
......
</ul>
步骤4:接下来,添加以下Javascript以读取data-dropdown-in / out数据属性,并对Bootstrap Javascript API钩子/事件(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');
});
}
},
});
第5步(可选):如果要加速或更改动画,可以使用CSS进行如下操作:
.dropdown-menu.animated {
/* Speed up animations */
-webkit-animation-duration: 0.55s;
animation-duration: 0.55s;
-webkit-animation-timing-function: ease;
animation-timing-function: ease;
}
如果有兴趣的话,写一篇更详细的文章并下载:文章:http : //bootbites.com/tutorials/bootstrap-dropdown-effects-animatecss
希望对您有所帮助,并且第二篇文章中有汤姆所需要的详细程度
这是一个很好的简单解决方案jQuery
,可以很好地工作:
$('.dropdown-toggle').click(function () {
$(this).next('.dropdown-menu').slideToggle(300);
});
$('.dropdown-toggle').focusout(function () {
$(this).next('.dropdown-menu').slideUp(300);
})
幻灯片动画切换是在单击时发生的,并且始终会在失去焦点时向上滑动。
将300
值更改为所需的任何值,数字越小动画越快。
编辑:
此解决方案仅适用于桌面视图。为了更好地显示在手机上,需要进行一些进一步的修改。
dropdown-toggle
),它再次消失,这意味着我无法选择子菜单项
自举3参考
添加是因为我一直被该线程中的解决方案所困扰,并且每次都使我感到困惑。
基本上,BS下拉列表会立即删除 .open
从父级中该类,因此向上滑动不起作用。
对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');
});
});
对于Bootstrap 3,上述答案的这种变化使移动slideUp()
动画更加流畅;上面的答案具有不稳定的动画,因为Bootstrap会.open
立即从切换的父级移除该类,因此此代码将还原该类直到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');
});
主要区别:
hide.bs.dropdown
事件处理程序中,我将.stop()
的默认值(false
)用于第二个参数(jumpToEnd
)hidden.bs.dropdown
事件处理程序恢复.open
类的下拉菜单切换的母公司,它几乎立即后级已经先取出做到这一点。同时,slideUp()
动画仍在运行,就像上面的答案一样,其“动画完成”回调负责最终删除动画。.open
从其父级类。截至撰写本文时,原始答案现在已经8岁了。我仍然觉得原始问题还没有适当的解决方案。
自那时以来,Bootstrap已经走了很长一段路,现在是4.5.2。这个答案解决了这个版本。
所有其他答案的问题是,当它们挂接到show.bs.dropdown
/时hide.bs.dropdown
,后续事件shown.bs.dropdown
/hidden.bs.dropdown
要么触发得太早(动画仍在进行中),要么由于被抑制(e.preventDefault()
)而根本不触发。
由于实施show()
和hide()
在引导程序Dropdown
类有一些相似之处,我在组合在一起,他们toggleDropdownWithAnimation()
mimicing原来的行为,并加入少许的生活质量辅助函数时showDropdownWithAnimation()
和hideDropdownWithAnimation()
。
toggleDropdownWithAnimation()
创建shown.bs.dropdown
/hidden.bs.dropdown
事件的方式与Bootstrap相同。就像您期望的那样,然后在动画完成后触发此事件。
/**
* Toggle visibility of a dropdown with slideDown / slideUp animation.
* @param {JQuery} $containerElement The outer dropdown container. This is the element with the .dropdown class.
* @param {boolean} show Show (true) or hide (false) the dropdown menu.
* @param {number} duration Duration of the animation in milliseconds
*/
function toggleDropdownWithAnimation($containerElement, show, duration = 300): void {
// get the element that triggered the initial event
const $toggleElement = $containerElement.find('.dropdown-toggle');
// get the associated menu
const $dropdownMenu = $containerElement.find('.dropdown-menu');
// build jquery event for when the element has been completely shown
const eventArgs = {relatedTarget: $toggleElement};
const eventType = show ? 'shown' : 'hidden';
const eventName = `${eventType}.bs.dropdown`;
const jQueryEvent = $.Event(eventName, eventArgs);
if (show) {
// mimic bootstraps element manipulation
$containerElement.addClass('show');
$dropdownMenu.addClass('show');
$toggleElement.attr('aria-expanded', 'true');
// put focus on initial trigger element
$toggleElement.trigger('focus');
// start intended animation
$dropdownMenu
.stop() // stop any ongoing animation
.hide() // hide element to fix initial state of element for slide down animation
.slideDown(duration, () => {
// fire 'shown' event
$($toggleElement).trigger(jQueryEvent);
});
}
else {
// mimic bootstraps element manipulation
$containerElement.removeClass('show');
$dropdownMenu.removeClass('show');
$toggleElement.attr('aria-expanded', 'false');
// start intended animation
$dropdownMenu
.stop() // stop any ongoing animation
.show() // show element to fix initial state of element for slide up animation
.slideUp(duration, () => {
// fire 'hidden' event
$($toggleElement).trigger(jQueryEvent);
});
}
}
/**
* Show a dropdown with slideDown animation.
* @param {JQuery} $containerElement The outer dropdown container. This is the element with the .dropdown class.
* @param {number} duration Duration of the animation in milliseconds
*/
function showDropdownWithAnimation($containerElement, duration = 300) {
toggleDropdownWithAnimation($containerElement, true, duration);
}
/**
* Hide a dropdown with a slideUp animation.
* @param {JQuery} $containerElement The outer dropdown container. This is the element with the .dropdown class.
* @param {number} duration Duration of the animation in milliseconds
*/
function hideDropdownWithAnimation($containerElement, duration = 300) {
toggleDropdownWithAnimation($containerElement, false, duration);
}
现在,我们已经编写了用于显示/隐藏带有动画的下拉菜单的正确回调,让我们实际将它们绑定到正确的事件。
我在其他答案中经常看到的一个常见错误是将事件侦听器直接绑定到元素。尽管这对于注册事件侦听器时出现的DOM元素来说很好用,但它不会绑定到以后添加的元素。
因此,通常最好直接绑定到document
:
$(function () {
/* Hook into the show event of a bootstrap dropdown */
$(document).on('show.bs.dropdown', '.dropdown', function (e) {
// prevent bootstrap from executing their event listener
e.preventDefault();
showDropdownWithAnimation($(this));
});
/* Hook into the hide event of a bootstrap dropdown */
$(document).on('hide.bs.dropdown', '.dropdown', function (e) {
// prevent bootstrap from executing their event listener
e.preventDefault();
hideDropdownWithAnimation($(this));
});
});