在 Bootstrap 3 中单击导航栏元素外部时如何关闭打开的折叠导航栏?
Posted
技术标签:
【中文标题】在 Bootstrap 3 中单击导航栏元素外部时如何关闭打开的折叠导航栏?【英文标题】:How to close an open collapsed navbar when clicking outside of the navbar element in Bootstrap 3? 【发布时间】:2014-07-09 00:20:09 【问题描述】:如何在单击导航栏元素外部时关闭打开的折叠导航栏?目前,打开或关闭它的唯一方法是单击navbar-toggle
按钮。
示例和代码见here:
到目前为止,我尝试了以下似乎不起作用的方法:
jQuery(document).click(function()
);
jQuery('.navbar').click(function(event)
jQuery(".navbar-collapse").collapse('hide');
event.stopPropagation();
);
【问题讨论】:
当我在菜单外单击时,演示中的“损坏”链接会关闭;什么坏了? @Paulie_D 我已经用我的尝试更新了我的问题。 @cDima 你指的是什么断开的链接?我没有看到。 我假设他的意思是“汉堡包”元素以适当的宽度打开菜单并重新单击将其关闭。我假设他希望在单击任意位置时发生相同的“关闭”。 所以只要在你的 JQuery 函数中选择body
就可以了,假设检查菜单是否打开。
【参考方案1】:
看看:
$(document).ready(function ()
$(document).click(function (event)
var clickover = $(event.target);
var _opened = $(".navbar-collapse").hasClass("navbar-collapse in");
if (_opened === true && !clickover.hasClass("navbar-toggle"))
$("button.navbar-toggle").click();
);
);
你的小提琴适用于:http://jsfiddle.net/52VtD/5718/
它是this answer的修改版,缺少动画,也稍微复杂一点。
我知道,调用 click()
不是很优雅,但 collapse('hide')
对我也不起作用,而且我认为动画比几乎添加和删除类要好一些。
【讨论】:
是的,我不确定为什么collapse('hide)
不起作用。不过,这个解决方案效果很好。
如果导航栏包含搜索框则不起作用,点击搜索文本输入一定不能关闭导航栏:jsfiddle.net/duongphuhiep/xtyb6wwu/1
无论出于何种原因,我在最新的引导程序 3 上都需要这个:.hasClass("navbar-collapse collapse in")
这在 angularJS 和 ui-router 中使用时非常好用。在 $stateChangeSuccess 上使用它非常好
如果使用 Aurelia 你可以这样使用this.eventAggregator.subscribe('router:navigation:success', response => jQuery("navigation button.navbar-toggle").click(); );
【参考方案2】:
接受的答案似乎无法正常工作。它只需要检查“navbar-collapse”是否有“in”类。然后我们可以使用导航栏的引用按预期触发折叠方法。
$(document).click(function (event)
var clickover = $(event.target);
var $navbar = $(".navbar-collapse");
var _opened = $navbar.hasClass("in");
if (_opened === true && !clickover.hasClass("navbar-toggle"))
$navbar.collapse('hide');
);
【讨论】:
对我来说进行了一次更改,效果很好。我会确保如果用户确实点击了不是链接的打开导航上的某个位置,它将保持打开状态。 如何将它与导航栏中的输入框结合起来?因为当我点击导航栏内的输入框时,导航栏也消失了。 是的,接受的答案也没有为我做任何事情。这行得通。 谢谢!我找这个太久了。 我在哪里可以添加这个?【参考方案3】:使用它对我有用。
$(function()
$(document).click(function (event)
$('.navbar-collapse').collapse('hide');
);
);
【讨论】:
您缺少一个右括号来终止 click 方法。 );【参考方案4】:我决定使用的解决方案取自此处接受的答案和this answer
jQuery('body').bind('click', function(e)
if(jQuery(e.target).closest('.navbar').length == 0)
// click happened outside of .navbar, so hide
var opened = jQuery('.navbar-collapse').hasClass('collapse in');
if ( opened === true )
jQuery('.navbar-collapse').collapse('hide');
);
如果用户单击.navbar
元素之外的任何位置,这将隐藏打开的折叠导航菜单。当然,点击.navbar-toggle
仍然可以关闭菜单。
【讨论】:
我会将body
更改为html
以解决高设备或内容很少的页面。 body 的高度与内容匹配,而不是可见的屏幕区域,因此如果您的页面内容很少,则不会触发内容区域下方的点击。否则,即使使用导航栏子菜单,也是一个很好的答案并且效果很好。
效果很好。要使其关闭菜单本身和导航栏切换按钮以外的任何单击,只需将第一个“.navbar”替换为“.navbar-collapse”,这样即使您单击导航栏中的其他链接,它仍然会关闭菜单。
我不得不从 hasClass 检查中删除“in”类,没有它就无法工作。可能是因为我的 .navbar-collapse 元素中没有“in”类。我正在使用引导程序 4。【参考方案5】:
Bootstrap 4(.3.1) 转换后的喷嘴人答案:
$(document).ready(function ()
$(document).click(
function (event)
var target = $(event.target);
var _mobileMenuOpen = $(".navbar-collapse").hasClass("show");
if (_mobileMenuOpen === true && !target.hasClass("navbar-toggler"))
$("button.navbar-toggler").click();
);
);
放置在 ngOnInit() 中。
加载文档时,此代码等待点击事件。如果移动菜单下拉菜单打开(即导航栏的可折叠部分具有“显示”类)并且单击的对象(目标)不是移动菜单按钮(即没有“导航栏切换器”类),则我们告诉移动菜单按钮它已被点击,然后菜单关闭。
【讨论】:
这对我有用。所有其他答案都是几年前的,可能不起作用。如果您按照指南使用 Bootstrap 4,这将起作用【参考方案6】:stopPropagation()
并不总是最好的解决方案。而是使用类似的东西:
jQuery(document.body).on('click', function(ev)
if(jQuery(ev.target).closest('.navbar-collapse').length) return; // Not return false
// Hide navbar
);
我认为假设您永远不想收听来自.navbar
的任何其他事件是很危险的。如果你使用stopPropagation()
,这是不可能的。
【讨论】:
嗨@pstenstrm。谢谢你,虽然它似乎不起作用?我已经用你的 jQuery 更新了 JSFIDDLE:jsfiddle.net/52VtD/5708 嗯,.navbar
几乎是整个文档的一部分。我已经更新了答案
注意点!我给 body 指定了 700px 的高度,所以 jsfiddle 更好地说明了正在发生的事情:jsfiddle.net/52VtD/5709 - 现在的问题是在 body 中单击会关闭并打开下拉菜单。我只需要关闭它。只能通过切换按钮 navbar-toggle
打开【参考方案7】:
我有一个场景,我有纯文本,如果用户意外单击纯文本,我不希望面板关闭。即使您单击不是链接的项目的文本,此处的其他答案将关闭面板。
为了解决这个问题,我在 Paul Tarr 的回答中添加了一个检查方法,以查看点击是否发生在内部任何地方:
if ($(event.target).parents(".navbar-collapse").length < 1)
完整的代码将变为:
$(document).click(function (event)
if ($(event.target).parents(".navbar-collapse").length < 1)
var clickover = $(event.target);
var $navbar = $(".navbar-collapse");
var _opened = $navbar.hasClass("in");
if (_opened === true && !clickover.hasClass("navbar-toggle"))
$navbar.collapse('hide');
);
在这个demo fiddle 中,您可以看到,如果您单击面板内的非链接,它不会折叠它。
【讨论】:
【参考方案8】:我在@nozzleman 的回答中添加了一个条件,以检查是否对菜单中的任何元素进行了点击或单击,如果是这样,请不要折叠它。
$(document).ready(function ()
$(document).click(function (event)
var clickover = $(event.target);
var _opened = $(".navbar-collapse").hasClass("navbar-collapse in");
if (_opened === true && !clickover.hasClass("navbar-toggle") && clickover.parents('.navbar-collapse').length == 0)
$("button.navbar-toggle").click();
);
);
【讨论】:
【参考方案9】:以下代码对我有用,其优点是在小屏幕上,当您使用 .navbar .navbar-expand 类单击其导航父级时,它不会隐藏 .collapse:
$(document).click(function (e)
if($('.collapse').hasClass('show') && !$('nav').is(e.target) && $('nav').has(e.target).length === 0)
$('.navbar-toggler').click()
)
【讨论】:
【参考方案10】:对于最新的 Bootstrap,这是正确的答案。
$(document).click(function (event)
var clickover = $(event.target);
var $navbar = $(".navbar-collapse");
var _opened = $navbar.hasClass("show");
if (_opened === true && !clickover.hasClass("navbar-toggler"))
$navbar.collapse('hide');
);
它会读取 .navbar-collapse 是否在类中包含单词 show(这意味着菜单已打开),并在您单击/点击任意位置时隐藏导航栏。
【讨论】:
【参考方案11】:对于引导程序 4
Bootstrap 4 没有 in
类。这是 Coffeescript。
$(document).click (e)->
#console.log e.target
unless $('#toggle-button').has(e.target).length || $('#toggle-menu').has(e.target).length
$('#toggle-menu').collapse('hide')
所以基本上,除非你点击按钮或菜单,否则关闭菜单。
注意:奇怪的是,在 ios 上点击文本不会注册点击事件,也不会注册 mouseup 事件。但是,单击图像会触发事件。
【讨论】:
【参考方案12】:对于引导程序 4:
$(document).click(function(event)
$(event.target).closest(".navbar").length || $(".navbar-collapse.show").length && $(".navbar-collapse.show").collapse("hide")
);
【讨论】:
请为您的答案添加解释。【参考方案13】:$(document).click(function (event)
if ($('.navbar-collapse').attr('aria-expanded') == "true")
$('.navbar-collapse:visible').click();
);
【讨论】:
【参考方案14】:$(window).click(function (e)
if ($(e.target).closest('.codehim-dropdown').length)
return;
if ($(e.target).closest(offCanvas).length)
return;
//check if menu really opened
if ($(hamburger).hasClass("active"))
closeMenu();
$(dimOverlay).fadeOut();
$(".menu-items").slideUp();
$(".dropdown-heading").removeClass("active");
);
【讨论】:
【参考方案15】:我在这里的一些答案有一些问题,我也希望能够按需关闭扩展菜单。所以我用一个简单的函数来模拟点击。
function closeMenu()
element = document.getElementById('nav_top');
if(element)
if(element.classList.contains('show'))
document.getElementById('navbar_toggler').dispatchEvent(new CustomEvent('click'));
$(document).ready(function ()
$(document).click(function (event)
closeMenu();
);
);
使用此方法,您可以在外部单击时关闭它,也可以随时从任何其他函数调用closeMenu()
。
【讨论】:
谢谢@Cosmin Staicu 更好地格式化我的答案。以上是关于在 Bootstrap 3 中单击导航栏元素外部时如何关闭打开的折叠导航栏?的主要内容,如果未能解决你的问题,请参考以下文章
如何在折叠的导航栏中默认打开 Bootstrap 3 下拉菜单