【问题标题】:How to close an open collapsed navbar when clicking outside of the navbar element in Bootstrap 3?在 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 就可以了,假设检查菜单是否打开。

标签: javascript jquery html css twitter-bootstrap-3


【解决方案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 更好地格式化我的答案。
                猜你喜欢
                • 2021-12-11
                • 2017-05-20
                • 2016-02-22
                • 2021-12-26
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2014-05-15
                • 2018-06-04
                相关资源
                最近更新 更多