O menu recolhido do Bootstrap 3 não fecha ao clicar

122

Eu tenho uma navegação mais ou menos padrão do bootstrap 3

<body data-spy="scroll" data-target=".navbar-collapse">
    <!-- ---------- Navigation ---------- -->
    <div class="navbar navbar-fixed-top" role="navigation">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
                    <span class="sr-only">Toggle navigation</span>
                </button>
                <a class="navbar-brand" href="index.html"> <img src="#"></a>
            </div>
            <div class="navbar-collapse collapse">
                <ul class="nav navbar-nav navbar-right">
                    <li class="active"><a href="#home">Home</a></li>
                    <li><a href="#one">One</a></li>
                    <li><a href="#two">Two</a></li>
                    <li><a href="#three">Three</a></li>
                    <li><a href="#four">Four</a></li>
                </ul>
            </div>
        </div>
    </div>

Ele cai normalmente em dispositivos menores. Clicar no botão de menu expande o menu, mas se eu clicar (ou tocar nesse assunto) em um link de menu, o menu permanecerá aberto. O que tenho que fazer para fechá-lo novamente?

Paranóia
fonte
5
a resposta do usuário3669917 é certamente a resposta mais fácil e direta!
Thomas
1
Possível duplicata do Ocultar o Twitter Bootstrap nav collapse on click
Inanc Gumus

Respostas:

48

A configuração padrão do Bootstrap é manter o menu aberto quando você clica em um item de menu. Você pode substituir manualmente esse comportamento chamando .collapse('hide');o elemento jQuery que deseja recolher.

VCNinc
fonte
8
Isso está errado, o bootstrap alterna automaticamente a classe "collapse". Você não precisa de nenhum código jquery adicional. Se você tem esse comportamento, significa que algo está errado no seu código html (da minha parte, eu incluí o jquery e o bootstrap duas vezes, veja a resposta de @raisercostin).
RomOne 15/02
@RomOne Esta resposta está correta. Bootstrap se não fechar o menu após links clicados por padrão. A outra resposta é aplicável apenas se as pessoas incluírem incorretamente o jQuery duas vezes, o que não é a resposta correta para esta pergunta.
Zim
136

Apenas para compartilhar isso das soluções no GitHub, esta foi a resposta popular:

https://github.com/twbs/bootstrap/issues/9013#issuecomment-39698247

$(document).on('click','.navbar-collapse.in',function(e) {
    if( $(e.target).is('a') ) {
        $(this).collapse('hide');
    }
});

Isso é conectado ao documento, para que você não precise fazê-lo em ready () (você pode anexar dinamicamente links ao menu e ele ainda funcionará), e só será chamado se o menu já estiver expandido. Algumas pessoas relataram piscadas estranhas onde o menu é aberto e depois são fechadas imediatamente com outro código que não verificava se o menu tinha a classe "in".

[ATUALIZAÇÃO 2014-11-04] aparentemente, ao usar submenus, os itens acima podem causar problemas; portanto, os itens acima foram modificados para:

$(document).on('click','.navbar-collapse.in',function(e) {
    if( $(e.target).is('a:not(".dropdown-toggle")') ) {
        $(this).collapse('hide');
    }
});
Kevin Nelson
fonte
1
Funciona perfeitamente. Obrigado por compartilhar!
Rodrigo Chiong 28/05
Você pode explicar '$ (this) .collapse (' hide ');' por favor. Eu não entendo de onde vem o 'colapso'
timebandit
@ImranNazir, desculpe, isso é muito posterior à pergunta, mas collapseé um método definido pelo bootstrap e anexado ao objeto jQuery ... presumivelmente, eles o reutilizam para vários propósitos (acordeão, barra de navegação etc.): getbootstrap.com/javascript / # collapse-use
Kevin Nelson
O código atualizado funcionou para mim, as respostas acima disso não. Obrigado!
RandomUs1r
O "[UPDATE 2014-11-04]" funcionou. Quanto à outra solução em que é recomendável remover a referência duplicada para bootstrap.js e jquery que não é necessária a solução. Encontrei esta solução para corrigir o problema com menos tempo para depuração e com comportamento mais explícito. Obrigado!. Espero que isso ajude você como me ajudou.
Nour Lababidi 06/10/19
122

Mude isso:

<li><a href="#one">One</a></li>

para isso:

<li><a data-toggle="collapse" data-target=".navbar-collapse" href="#one">One</a></li>  

Essa simples mudança funcionou para mim.

Ref: https://github.com/twbs/bootstrap/issues/9013

FullStackDev
fonte
14
Esta solução é adequada para a visualização Móvel, mas mostra mostrar / ocultar animação em telas grandes quando o link é clicado.
Ayman Al-Absi
22
@ AymanAl-Absi Você tem que adicionar .inao final do data-targetvalor: data-target=".navbar-collapse.in". Do comentário nesta resposta: stackoverflow.com/a/21797534/89818
caw
isso funciona muito bem para mim, mas quebra o scrollspy, alguma idéia do porquê?
Craig Harley
1
Trabalhou para mim quando atualizado acima do código com a resposta @caw. Também estou usando o recurso scrollspy.
precisa
Esta é de longe a melhor solução. Sem javascript, sem jQuery. Se você deseja que determinado link mantenha o menu aberto, não adicione esses parâmetros. Deve ser apontado como a melhor resposta. Obrigado.
Ed1nh0
55

Eu tive o mesmo problema, mas causado pela inclusão de duas vezes bootstrap.js e jquery.jsarquivos.

Em um único clique, o evento foi processado duas vezes pelas duas instâncias de jquery. Um fechou e outro abriu a alavanca.

raisercostin
fonte
3
Eu tinha exatamente o mesmo problema, mas não sabia que eles estavam sendo incluídos duas vezes. Obrigado por postar isso!
Brian ONeil
2
Nosso estagiário também. Obrigado por postar isso.
Teisman 21/07
2
Homem! Fiz a mesma coisa - acho que estou voltando a ser estagiário!
Dicer
2
Tão útil! Eu estava trabalhando nisso há dias. Isso pode ser muito comum ao usar um modelo da barra de navegação. Tenha cuidado com as pessoas! :)
Matt Butler
2
Isso deve ser marcado como a melhor resposta. Eu tive o mesmo problema removendo bootstrap.js resolveu o problema
katwekibs
17
$(".navbar-nav li a").click(function(event) {
    if (!$(this).parent().hasClass('dropdown'))
        $(".navbar-collapse").collapse('hide');
});

Isso ajudaria no manuseio suspenso na barra de navegação

Chakradhar Vyza
fonte
Isso corrigiu meu problema, ao usar problemas de inicialização com o javascript de uma apresentação de slides do jssor. Esse código também cria um efeito interessante ao expandir e recolher o menu móvel.
Adam West
Obrigado @Chakradhar, economizou meu tempo.
Omar Bahir
Obrigado, esquecemos que o Laravel 5.5 JS inclui B e Jquery no arquivo js principal.
Jack Vial
12

Estou tendo / tive problemas semelhantes com o Bootstrap 4, alpha-6 e a resposta de Joakim Johansson acima me levou na direção certa. Não é necessário javascript. Colocar data-target = ". Navbar-collapse" e data-toggle = "collapse" na tag div dentro da nav, mas ao redor dos links / botões, funcionou para mim.

<div class="navbar-nav" data-target=".navbar-collapse" data-toggle="collapse">
   <a class="nav-item nav-link" href="#">Menu Item 1</a>
   ...
</div>

Paulo
fonte
Sua postagem me ajudou muito. Isso resolveu para mim <body data-toggle = "collapse" data-target = ". Navbar-collapse">
Dessus
Isso já foi publicado há 3 anos. Além disso, ele interrompe a animação na exibição não móvel.
Bevor
6

Eu sei que esta pergunta é para o Bootstrap 3, mas se você estiver procurando uma solução para o Bootstrap 4 , faça o seguinte:

$(document).on('click','.navbar-collapse.show',function(e) {
  $(this).collapse('hide');
});
Syed
fonte
Estou usando o BS4 beta e seu código funciona perfeitamente. Tentei todas as outras soluções sugeridas aqui sem sorte. Aparentemente, o BS4 mudou o suficiente para que outras soluções simplesmente não se apliquem.
Bicycle Dave
Por relevância e manter as coisas em simultâneo com informações atualizadas - Essa deve ser a melhor resposta.
Ricky
@Ricky OP especificado Bootstrap 3, não 4.
Malavos
Para menus com menus suspensos, usei o seguinte:$(".navbar-nav li a:not('.dropdown-toggle')") .on('click', function () { $('.navbar-collapse').collapse('hide'); }
James Wilkins
5

Eu tive o mesmo problema, estava usando jQuery-1.7.1e bootstrap 3.2.0. Alterei minha versão do jQuery para a versão mais recente ( jquery-1.11.2) e tudo funciona bem.

Densol
fonte
5

eu fiz

$(".navbar-toggle").click(function(event) {
    $(".navbar-collapse").toggle('in');
});
tecer
fonte
4

Embora a solução publicada anteriormente para alterar o item de menu em si, como abaixo, funcione quando o menu está em um dispositivo pequeno, ela tem um efeito colateral quando o menu está em largura total e expandido, isso pode resultar em uma barra de rolagem horizontal deslizando sobre o seu itens de menu . As soluções javascript não têm esse efeito colateral.

<li><a href="#one">One</a></li> to 
<li><a data-toggle="collapse" data-target=".navbar-collapse" href="#one">One</a></li>  

(desculpe-me por responder assim, queria adicionar um comentário a essa resposta, mas parece que não tenho crédito suficiente para fazer comentários)

Wim Van Houts
fonte
2
 $(function(){ 
    var navMain = $("#your id");
    navMain.on("click", "a", null, function () {
      navMain.collapse('hide');
    });
});
Chit
fonte
confira a nova versão Matthias S :-)
Chit
@bfontaine Primeiro, você precisa adicionar um id no menu div e, quando clicar no menu, o menu ficará oculto. Por exemplo: - Ao clicar no menu sobre nós, a guia do menu restante será ocultada.
Chit
1
obrigado, mas por favor, escreva que em sua resposta;)
bfontaine
1

Caso você queira substituir manualmente esse comportamento chamando .collapse ('hide') dentro da diretiva de uma angular, eis o código:

arquivo javascript:

angular
  .module('yourAppModule')
  .directive('btnAutoCollapse', directive);

function directive() {
  var dir = {
    restrict: 'A',
    scope: {},
    link: link
  };
  return dir;

  function link(scope, element, attrs) {    
    element.on('click', function(event) {              
      $(".navbar-collapse.in").collapse('hide');
    });
  }
}

Html:

<li class="navbar-btn">
     <a href="#" ng-hide="username" **btn-auto-collapse**>Sign in</a>
</li>
Mirna De Jesus
fonte
1

Verifique se você está usando a versão mais recente do bootstrap js. Eu estava enfrentando o mesmo problema e apenas atualizar o arquivo bootstrap.js do bootstrap-3.3.6 fez a mágica.

Aman Arun
fonte
1

Se você deseja apenas alternar sua navegação quando usada em uma tela móvel, basta adicionar data-toggle="collapse"e adicionar data-target="#navbar"elementos aos elementos a que funcionarão na tela móvel, mas lhe dará uma cintilação estranha quando clicada na tela da área de trabalho. As soluções jQuery não funcionam bem se você estiver em um ambiente Aurelia ou Angular.

A melhor solução para mim foi criar um atributo personalizado que escute a consulta de mídia correspondente e adicione o data-toggle="collapse"atributo, se desejado:

<a href="#" ... collapse-toggle-if-less768 data-target="#navbar"> ...

O atributo personalizado com Aurelia se parece com isso:

import {autoinject} from 'aurelia-framework';

@autoinject
export class CollapseToggleIfLess768CustomAttribute {
  element: Element;

  constructor(element: Element) {
    this.element = element;
    var mql = window.matchMedia("(min-width: 768px)");
    mql.addListener((mediaQueryList: MediaQueryList) => this.handleMediaChange(mediaQueryList));
    this.handleMediaChange(mql);
  }

  handleMediaChange(mediaQueryList: MediaQueryList) {
    if (mediaQueryList.matches) {
      var dataToggle = this.element.attributes.getNamedItem("data-toggle");
      if (dataToggle) {
        this.element.attributes.removeNamedItem("data-toggle");
      }
    } else {
      var dataToggle = this.element.attributes.getNamedItem("data-toggle");
      if (!dataToggle) {
        var dataToggle = document.createAttribute("data-toggle");
        dataToggle.value = "collapse";
        this.element.attributes.setNamedItem(dataToggle);
      }
    }
  }
}

Halllo
fonte
0

Descobri que, depois de muita luta, tentativa e erro, a melhor solução para mim no jsfiddle. Link para inspiração em jsfiddle.net . Estou usando o navbar navbar-nav-fix-top do bootstrap com alternância de recolhimento e hambúrguer. Aqui está a minha versão no jsfiddle: jsfiddle Scrollspy navbar . Eu estava obtendo apenas a funcionalidade básica usando as instruções em getbootsrap.com. Para mim, o problema estava principalmente nas direções vagas e js recomendadas pelo site getbootstrap. A melhor parte foi que a adição desse bit extra de js (que inclui parte do que é mencionado nos tópicos acima) resolveu vários problemas do Scrollspy para mim, incluindo:

  1. O menu de navegação recolhido / alternado é oculto quando clica em "seção" de navegação (por exemplo, href = "# foobar") (problema ao abordar este tópico).
  2. A "seção" ativa foi destacada com sucesso (ou seja, js criou com sucesso class = "active")
  3. A barra de rolagem vertical irritante encontrada na navegação recolhida (apenas em telas pequenas) foi eliminada.

NOTA: No código js mostrado abaixo (a partir do segundo link jsfiddle no meu post):

topMenu = $ ("# myScrollspy"),

... o valor "myScrollspy" deve corresponder ao id = "" no seu HTML da seguinte forma ...

<nav id="myScrollspy" class="navbar navbar-default navbar-fixed-top">

Claro que você pode alterar esse valor para o valor que desejar.

Adam Calihman
fonte
0

Tudo que você precisa é data-target = ". Navbar-collapse" no botão, nada mais.

<button class="navbar-toggle" type="button" data-toggle="collapse" data-target=".navbar-collapse">
    <span class="sr-only">Toggle navigation</span>
    <span class="icon-bar"></span>
    <span class="icon-bar"></span>
    <span class="icon-bar"></span>
</button>
Marodo
fonte
+1: Ele também funciona adicionando data-toggle = "collapse" data-target = ". Navbar-collapse" a <a /> ou, no meu caso, <Link /> no Meteorjs com React, obrigado.
Joe L.
sim, funciona, <a/>mas não funciona <NavLink/>, entra em colapso, mas, <NavLink/>não está mais funcionando, nenhuma idéia do porquê?
A pirâmide
0

Este é o código que funcionou para mim:

jQuery('document').ready(function()
{   
   $(".navbar-header button").click(function(event) {
   if ($(".navbar-collapse").hasClass('in'))
   {  $(".navbar-collapse").slideUp();  }
});})
Roddy P. Carbonell
fonte
0

Eu tive o mesmo problema, verifique se o bootstrap.js está incluído na sua página html. No meu caso, o menu foi aberto, mas não foi fechado. Assim que incluí o arquivo js do bootstrap, tudo funcionou.

Elitmiar
fonte
0

Simples Tente criar uma função em javascript para a classe de recolhimento suspenso.

Exemplo:

JS :

$scope.toogleMyClass  = function(){

    //dropdown-element

    $timeout(function(){
        $scope.preLoader = false;
        $(document).ready(function() {
            $("#dropdown-element").toggleClass('show');
        });
    },100);

};

Ligue esta função a onClicktrabalhos simples para mim.

yasir_mughal
fonte
0

Eu tive o problema semelhante, mas o meu não ficou aberto, ele foi aberto / fechado rapidamente, descobri que o jquery-1.11.1.min.js estava carregando antes do bootstrap.min.js. Então, eu invertei a ordem desses 2 arquivos e arrumei meu menu. Agora funciona perfeitamente. Espero que ajude

Vasko
fonte
0

O problema pode ser que você está usando versões desatualizadas do bootstrap ou jquery, OU está chamando mais de uma versão na sua marcação.

Basta manter as versões mais recentes, você só precisa de uma referência. Resolve o problema.

usuario
fonte
0

convém garantir que você esteja carregando seu ATF jQuery e Bootstrap.min.js. Sua navegação é a primeira coisa a renderizar na página; portanto, se você tiver seus scripts na parte inferior do HTML, estará perdendo qualquer funcionalidade JavaScript.

Chris Johnson
fonte
0

Eu tive o mesmo problema apenas no celular, mas para um aplicativo Angular, e foi o que fiz:

app.component.html

<nav class="navbar navbar-default navbar-fixed-top">
  <div class="container">
    <div class="col-md-12">
      <div class="navbar-header page-scroll">
      <button id ="navButton" style="color:red"type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
          <span class="sr-only">Toggle navigation</span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </button>
        <a class="navbar-brand" routerLink="/"><img id="navbrand" class="site-logo"  src="assets/img/yayaka_logo.png"/></a>
    </div>
    <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
      <ul class="nav navbar-nav navbar-right">
        <li class="hidden">
          <a href="#page-top"></a>
        </li>
        <li class="dropdown" appDropdown>
          <a class="dropdown-toggle" style="cursor: pointer;">
            ΤΙ ΕΙΝΑΙ ΤΟ yayaka<span class="caret"></span>
          </a>
          <ul class="dropdown-menu">
            <li><a (click) = "closeMenu()" href="/#about">About</a></li>
            <li><a (click) = "closeMenu()" href="/#services">Services</a></li>
          </ul>
        </li>
        <li class="page-scroll">
          <a (click) = "closeMenu()" routerLink="/profiles"><strong>Profiles</strong></a>
        </li>
      </ul>
    </div>
  </div>
  </div>
</nav>

app.component.ts

 closeMenu() {
    var isMobile = /iPhone|iPad|iPod|BlackBerry|Opera Mini|IEMobile|Android/i.test(navigator.userAgent);
    if (isMobile) {
      document.getElementById('navButton').click();
    }
  }

Espero que ajude :)

Stathoula
fonte
-2

Meu menu não é padrão da barra de navegação, mas eu consegui recolher o meu automaticamente, usando a função "onclick" e a ".click ()".

<div class="main-header">
    <div class="container">
        <div id="menu-wrapper">
            <div class="row">

                <div class="logo-wrapper col-lg-4 col-md-6 col-sm-7 hidden-xs">

                </div> <!-- /.logo-wrapper -->

                <div class="logo-wrapper2 visible-xs col-xs-9">

                </div> <!-- /.smaller logo-wrapper -->

                <div class="col-lg-8 col-md-6 col-sm-5 col-xs-3 main-menu text-center">
                    <ul class="menu-first hidden-md hidden-sm hidden-xs">
                        <li class="active"><a href="#">item1</a></li> |
                        <li><a href="#our-team">item2</a></li> |
                        <li><a href="#services">item3</a></li> |
                        <li><a href="#elia">item4</a></li> |
                        <li><a href="#portfolio">item5</a></li> |
                        <li><a href="#contact">item6</a></li>
                    </ul>
                    <a href="#" class="toggle-menu visible-md visible-sm visible-xs"><i class="fa fa-bars"></i></a>
                </div> <!-- /.main-menu -->
            </div> <!-- /.row -->
        </div> <!-- /#menu-wrapper -->
        <div class="menu-responsive hidden-lg">
            <ul>
                <li class="active" onclick = $(".toggle-menu").click();><a href="#">item1</a></li>
                <li><a href="#our-team" onclick = $(".toggle-menu").click();>item2</a></li>
                <li><a href="#services" onclick = $(".toggle-menu").click();>item3</a></li>
                <li><a href="#elia" onclick = $(".toggle-menu").click();>item4</a></li>
                <li><a href="#portfolio" onclick = $(".toggle-menu").click();>item5</a></li>
                <li><a href="#contact" onclick = $(".toggle-menu").click();>item6</a></li>
            </ul>
        </div> <!-- /.menu-responsive -->
    </div> <!-- /.container -->
</div> <!-- /.main-header 
Bravo Stefane
fonte