Bootstrap close menu responsivo “no clique”

86

Em "PRODUTOS", clique em deslizar para cima um div branco (como mostrado no anexo). Quando estiver no responsivo (celular e tablet), gostaria de fechar automaticamente a barra de navegação responsiva e mostrar apenas a barra branca.

Eu tentei:

$('.btn-navbar').click();  

também tentei:

$('.nav-collapse').toggle();

E funciona. No entanto, no tamanho do desktop, ele também é chamado e faz algo estranho no menu, diminuindo por um segundo.

Alguma ideia?

insira a descrição da imagem aqui

user1040259
fonte
Você poderia postar algum HTML? Você também está usando o Bootstrap para a funcionalidade de ocultar? Ou você está tentando implementar algo próprio?
Kris Hollenbeck
Estou apenas tentando fazer algo simples, acho. Só quero fechar a barra de navegação quando clico em "PRODUTOS"
user1040259
Se você não quiser tentar e comparar todas essas soluções aqui sozinho, a edição # 1 desta resposta é o que você deve fazer.
caw
Eu recomendo rolar um pouco para baixo aqui e olhar a resposta @LukeTillman. Funciona perfeitamente e sem jQuery. :)
das Keks

Respostas:

101

Tenho que trabalhar com animação!

Menu em html:

<div id="nav-main" class="nav-collapse collapse">
     <ul class="nav">
         <li>
             <a href='#somewhere'>Somewhere</a>
         </li>
     </ul>
 </div>

Evento de clique de vinculação em todos os elementos na navegação para recolher o menu (plugin de recolhimento do Bootstrap):

 $(function(){ 
     var navMain = $("#nav-main");
     navMain.on("click", "a", null, function () {
         navMain.collapse('hide');
     });
 });

EDITAR Para torná-lo mais genérico, podemos usar o seguinte trecho de código

 $(function(){ 
     var navMain = $(".navbar-collapse"); // avoid dependency on #id
     // "a:not([data-toggle])" - to avoid issues caused
     // when you have dropdown inside navbar
     navMain.on("click", "a:not([data-toggle])", null, function () {
         navMain.collapse('hide');
     });
 });
mollwe
fonte
3
Se não forem todos os aelementos: você só precisa ligar$("#nav-main").collapse('hide');
Ankit Jain
@mollwe Você tem uma solução para quando tem um menu suspenso? Fiz um jsfiddle para tentar, mas nem o menu abre. jsfiddle.net/Y3H92
clankill3r
@ clankill3r parece-me que falta uma referência ao bootstrap.js e, portanto, o menu não funciona. Atualizei seu jsfiddle: jsfiddle.net/Y3H92/1
mollwe
@mollwe com seu violino, o menu não fecha de jeito nenhum para mim.
clankill3r
1
Desculpe pela resposta tardia @ clankill3r! Mas antes tarde do que nunca. jsfiddle.net/mollwe/Y3H92/5
mollwe
135

Você não precisa adicionar nenhum javascript extra ao que já está incluído com a opção de recolhimento de bootstraps. Em vez disso, simplesmente inclua os seletores de alternância de dados e de destino de dados em seus itens de lista de menu, assim como você faz com o botão de alternância da barra de navegação. Portanto, para o item do menu Produtos, seria assim

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

Em seguida, você precisaria repetir os seletores de alternância de dados e alvo de dados para cada item do menu

EDITAR!!! A fim de corrigir problemas de estouro e oscilação nesta correção, estou adicionando mais alguns códigos que irão consertar isso e ainda não tem nenhum javascript extra. Aqui está o novo código:

<li><a href="#products" class="hidden-xs">Products</a></li>
<li><a href="#products" class="visible-xs" data-toggle="collapse" data-target=".navbar-collapse">Products</a></li>

Aqui está ele no trabalho http://jsfiddle.net/jaketaylor/84mqazgq/

Isso tornará seus seletores de alternância e alvo específicos para o tamanho da tela e eliminará falhas no menu maior. Se alguém ainda estiver tendo problemas com falhas, entre em contato e eu encontrarei uma solução. obrigado

EDIT : No bootstrap v4.1.3 não consegui usar classes visíveis / ocultas. Em vez de hidden-xsusar d-none d-sm-blocke em vez de visible-xsusar d-block d-sm-none.

Jake Taylor
fonte
14
que causa cintilação e coisas estranhas quando o nav não é exibido como o menu "responsivo".
Florian,
5
Esta é a implementação correta. Nenhum jQuery customizado necessário.
larrylampco
Eu removi meu voto negativo sobre esta resposta e meu comentário anterior (também porque o vídeo não estava mais funcionando). como meu comentário sobre cintilação ainda é válido para a resposta original, recebi alguns votos positivos e sua "edição" está claramente marcada, não vejo razão para removê-lo e reescrever o histórico. era válido na época e você reagiu de acordo. as pessoas que lerem sua resposta verão a "edição" e saberão que você melhorou ...
Florian
Você prefere duplicar todos os seus links apenas para evitar uma única linha de javascript perfeitamente documentado? getbootstrap.com/javascript/#collapse-methods .
Sander Garretsen
1
Em vez de adicionar os atributos data-togglee data-targeta cada elemento li, você pode adicioná-los ao pai ulou às divtags.
Jeremy Quick
40

Acho que você é especialista em engenharia ..

    $('.navbar-collapse ul li a').click(function(){ 
            $('.navbar-toggle:visible').click();
    });

EDITAR: para cuidar dos submenus, certifique-se de que sua âncora de alternância tenha a classe de alternância suspensa nela.

    $(function () { 
            $('.navbar-collapse ul li a:not(.dropdown-toggle)').click(function () { 
                    $('.navbar-toggle:visible').click(); 
            }); 
    });

EDIT 2: Adicionar suporte para toque de telefone.

    $(function () {
            $('.navbar-collapse ul li a:not(.dropdown-toggle)').bind('click touchstart', function () {
                    $('.navbar-toggle:visible').click();
            });
    });
Hontoni
fonte
3
Deve ser a resposta aceita. Os outros têm engenharia excessiva e cintilam na tela sem resposta.
rybo111
3
Esta poderia ser a resposta aceita, mas não leva em consideração os submenus e, na verdade, os quebra. Algumas das outras soluções de "engenharia excessiva" levaram isso em consideração, apesar de suas deficiências. A seguinte adição tomará conta disso: $ (function () {$ ('. Navbar-collapse ul li a: not (.dropdown-toggle)'). Click (function () {$ ('. Navbar-toggle: visível '). click ();});});
Ed Bishop
ótimo, obrigado pela sua edição!
Hontoni
1
Acho que o touchstart é um pouco demais, clicar funciona bem. como ele responde ao deslizar quando você "inicia" a partir do botão?
Hontoni
37

Eu realmente gostei da ideia de Jake Taylor de fazer isso sem JavaScript adicional e tirar vantagem do seletor de colapso do Bootstrap. Descobri que você pode corrigir o problema de "oscilação" presente quando o menu não está no modo recolhido, modificando data-targetligeiramente o seletor para incluir a inclasse. Então fica assim:

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

Eu não testei com menus suspensos / aninhados, então YMMV.

Luke Tillman
fonte
3
Esta foi a melhor implementação para mim também.
huijing
Por alguma razão, meu ScrollSpy rompe com esse método, mas funciona bem com o método de Jake Taylor.
Inkling de
A melhor e mais simples resposta até agora.
Diaa
Estou tentando fazer um colapso sem cintilação funcionar há algum tempo, mas esta é de longe a solução mais simples e elegante. Obrigado!
McVenco
8

só para ficar completo, no Bootstrap 4.0.0-beta usando .show funcionou para mim ...

<li>
  <a href="#Products" data-toggle="collapse" data-target=".navbar-collapse.show">Products</a>
</li>
vidriduch
fonte
5

Estou assumindo que você tem uma linha como esta definindo a área de navegação, com base em exemplos de Bootstrap e todos

<div class="nav-collapse collapse" >

Basta adicionar as propriedades como tal, como no botão MENU

<div class="nav-collapse collapse" data-toggle="collapse"  data-target=".nav-collapse">

Eu também adicionei <body>, funcionou. Não posso dizer que criei um perfil ou algo assim, mas parece um prazer para mim ... até que você clique em um ponto aleatório da IU para abrir o menu, então não é tão bom assim.

DK

Douglas 'DK' Knudsen
fonte
Solução adequada com base na funcionalidade interna do Bootstrap; sem jQuery ou javascript adicional. E a solução mais simples de todas. Esta deve ser a resposta aceita.
Sergi Papaseit
4

Isso funciona, mas não anima.

$('.btn-navbar').addClass('collapsed');
$('.nav-collapse').removeClass('in').css('height', '0');
user1040259
fonte
8
É um pouco surpreendente que não haja uma opção de configuração para isso, pois fechar ao clicar seria um padrão melhor.
bchesley,
3

No HTML eu adicionei uma classe de nav-link à uma tag de cada link de navegação.

$('.nav-link').click(
    function () {
        $('.navbar-collapse').removeClass('in');
    }
);
Jason Swingen
fonte
3

esta solução tem um bom trabalho, tanto no desktop quanto no celular.

<div id="navbar" class="navbar-collapse collapse" data-toggle="collapse"  data-target=".navbar-collapse collapse">
bp002
fonte
funcionou para mim ao usar o navbar-id como data-target: <div id = "navbar" class = "collapse navbar-collapse" data-toggle = "collapse" data-target = "# navbar"> mas apresenta uma animação feia enquanto no tamanho do desktop
wutzebaer
Muito feio, inaceitável!
candlejack
2

Apenas para explicar a solução do user1040259, adicione este código ao seu $ (document) .ready (function () {});

    $('.nav').click( function() {
        $('.btn-navbar').addClass('collapsed');
        $('.nav-collapse').removeClass('in').css('height', '0');
    });

Como eles mencionaram, isso não anima o movimento ... mas fecha a barra de navegação na seleção do item

CharlesA
fonte
2

Para aqueles que usam AngularJS e Angular UI Router com isso, aqui está minha solução (usando a chave de alternância de mollwe). Onde ".navbar-main-collapse" é o meu "alvo de dados".

Criar diretiva:

module.directive('navbarMainCollapse', ['$rootScope', function ($rootScope) {
    return {
        restrict: 'C',
        link: function (scope, element) {
            //watch for state/route change (Angular UI Router specific)
            $rootScope.$on('$stateChangeSuccess', function () {
                if (!element.hasClass('collapse')) {
                    element.collapse('hide');
                }
            });
        }
    };
}]);

Diretriz de uso:

<div class="collapse navbar-collapse navbar-main-collapse">
    <your menu>
Kyle
fonte
Parece que você colocou a diretiva na classe attr, certo?
Gringo Suave
Dentro da função de link, o seguinte deve funcionar. element.on ('click', function () {scope.vm.isCollapsed =! scope.vm.isCollapsed;});
JimmyBob
2

Isso deve funcionar.

Requer bootstrap.js.

Exemplo => http://getbootstrap.com/javascript/#collapse

    $('.nav li a').click(function() {
      $('#nav-main').collapse('hide');
    });

Isso faz a mesma coisa que adicionar os atributos 'data-toggle = "collapse"' e 'href = "yournavigationID"' às tags dos menus de navegação.

Jussi Järviö
fonte
Você poderia explicar a resposta com mais detalhes?
Blunderfest
Isso não é jQuery? Não é uma prática geralmente ruim usar jQuery e Angular?
AlxVallejo
1

Estou usando a função mollwe, embora tenha adicionado 2 melhorias:

a) Evite o fechamento da lista suspensa se o link clicado estiver recolhido (incluindo outros links)

b) Oculte a lista suspensa também, se você estiver clicando no conteúdo da web visível.

jQuery.fn.exists = function() {
                  return this.length > 0;
              }

    $(function() {
                var navMain = $(".navbar-collapse");
                navMain.on("click", "a", null, function() {
                    if ($(this).attr("href") !== "#") {
                        navMain.collapse('hide');
                    }
                });

                $("#content").bind("click", function() {
                     if ($(".navbar-collapse.navbar-ex1-collapse.in").exists()) {
                        navMain.collapse('hide');
                    }
                });

            });
Arco voltaico
fonte
1

Não é o tópico mais recente, mas procurei uma solução para o mesmo problema e encontrei uma (uma mistura de alguns outros).

Eu dei o NavButton:

<type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> ...

um id / identificador como:

 <button id="navcop" type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">

Não é a melhor "ideia" - mas: Funciona para mim! Agora você pode verificar a visibilidade do seu botão (com jquery) como:

 var target = $('#navcop');
   if(target.is(":visible")){
   $('#navcop').click();
   }

(NOTA: Este é apenas um código cortado! Usei um evento "onclick" em meus links de navegação! (Iniciando um Reguest AJAX.)

O resultado é: Se o botão está "visível", ele foi "clicado" ... Então: Não há Bug se você usar a "Visualização em tela cheia" do Bootstrap (largura de mais de 940px).

Saudações Ralph

PS: Funciona bem com IE9, IE10 e Firefox 25. Não verifiquei outros - mas não consigo ver um problema :-)

Ralph D.
fonte
1

Isso funcionou para mim. Eu fiz assim, quando clico no botão de menu, estou adicionando ou removendo a classe 'in', porque ao adicionar ou remover essa classe o alternador está funcionando por padrão. 'e.stopPropagation ()' é para parar a animação padrão por bootstrap (eu acho) você também pode usar o 'toggleClass' no lugar de adicionar ou remover classe.

$ ('# ChangeToggle'). On ('click', function (e) {

        if ($('.navbar-collapse').hasClass('in')) {
            $('.navbar-collapse').removeClass('in');
            e.stopPropagation();
        } else {
            $('.navbar-collapse').addClass('in');
            $('.navbar-collapse').collapse();
        }

    });
Goutami
fonte
0

Você pode usar

ul.nav {
    display: none;
}

Por padrão, isso fechará a barra de navegação. Por favor, deixe-me saber se alguém achar isso útil

Kris
fonte
2
O problema é que isso oculta o nav quando exibido "normalmente", não no menu responsivo.
Florian de
0

Se, por exemplo, seu ícone alternável estiver visível apenas para dispositivos muito pequenos, você pode fazer algo assim:

$('[data-toggle="offcanvas"]').click(function () {
    $('#side-menu').toggleClass('hidden-xs');
});

Clicar em [data-toggle = "offcanvas"] adicionará .hidden-xs do bootstrap ao meu # menu lateral, o que ocultará o conteúdo do menu lateral, mas ficará visível novamente se você aumentar o tamanho da janela.

Kingsley Ijomah
fonte
0

se o menu HTML for

<div id="nav-main" class="nav-collapse collapse">
     <ul class="nav">
         <li>
             <a href='#somewhere'>Somewhere</a>
         </li>
     </ul>
</div>

on nav alternar 'na' classe é adicionado e removido do alternador. verifique se o menu responsivo está aberto e, em seguida, alterne para fechar.

$('.nav-collapse .nav a').on('click', function(){
    if ( $( '.nav-collapse' ).hasClass('in') ) {
        $('.navbar-toggle').click();
    }
});
Aamer Shahzad
fonte
0

Tuggle Nav Close, resposta compatível com o navegador IE, sem nenhum erro de console. Se você estiver usando bootstrap, use este

$('.nav li a').on('click', function () {
    if ($("#navbar").hasClass("in")) {
        $('.navbar-collapse.in').show();
    }
    else {
        $('.navbar-collapse.in').hide();
    }
})
Super Model
fonte
-1
$('.navbar-toggle').trigger('click');
Aqib
fonte
Não entendo por que essa não é a resposta certa. sempre que você clicar em qualquer link de menu nesse evento de clique, você pode alternar o menu, o que eu acho que é o caminho certo, porque não estou alterando o comportamento padrão de abrir ou fechar o menu.
Aqib
-1

Solução Bootstrap 4 sem qualquer Javascript

Adicione atributos data-toggle="collapse" data-target="#navbarSupportedContent.show" ao div<div class="collapse navbar-collapse">

Certifique-se de fornecer o correto idemdata-target

<div className="collapse navbar-collapse" id="navbarSupportedContent" data-toggle="collapse" data-target="#navbarSupportedContent.show">

.show é evitar que o menu pisque em grandes resoluções

<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<nav class="navbar navbar-expand-lg navbar-light bg-light">
  <a class="navbar-brand" href="#">Navbar</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>

  <div class="collapse navbar-collapse" id="navbarSupportedContent" data-toggle="collapse" data-target="#navbarSupportedContent.show">
    <ul class="navbar-nav mr-auto">
      <li class="nav-item active">
        <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">Link</a>
      </li>
      <li class="nav-item dropdown">
        <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
          Dropdown
        </a>
        <div class="dropdown-menu" aria-labelledby="navbarDropdown">
          <a class="dropdown-item" href="#">Action</a>
          <a class="dropdown-item" href="#">Another action</a>
          <div class="dropdown-divider"></div>
          <a class="dropdown-item" href="#">Something else here</a>
        </div>
      </li>
      <li class="nav-item">
        <a class="nav-link disabled" href="#">Disabled</a>
      </li>
    </ul>
    <form class="form-inline my-2 my-lg-0">
      <input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
      <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
    </form>
  </div>
</nav>

Kiranvj
fonte