Bootstrap navbar Active State not working


91

Eu tenho bootstrap v3.

Eu uso class="active"no meu navbare ele não muda quando pressiono os itens do menu. Eu sei como fazer isso jQuerye criar uma função de clique, mas estou pensando que essa funcionalidade deve ser incluída no bootstrap? Então, talvez seja um problema de JavaScript?

Aqui está meu cabeçalho com meus arquivos js / css / bootstrap que incluí:

<!-- Bootstrap CSS -->
<link rel="stylesheet" href= "/bootstrap/css/bootstrap.css" />
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css" />
<link rel="stylesheet" href= "/stylesheets/styles.css" />

<!--jQuery -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>

<!-- Bootstrap JS -->
<script src="/bootstrap/js/bootstrap.min.js"></script>
<script src="/bootstrap/js/bootstrap-collapse.js"></script>
<script src="/bootstrap/js/bootstrap-transition.js"></script>

Aqui está meu navbarcódigo:

<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
        <div class="container-fluid">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbarCollapse">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>

                <a class="navbar-brand" href="/index.php">MyBrand</a>
            </div>

            <div class="collapse navbar-collapse navbarCollapse">
                <ul class="nav navbar-nav navbar-right">
                    <li class="active">
                        <a href="/index.php">Home</a>
                    </li>

                    <li>
                        <a href="/index2.php"> Links</a>
                    </li>

                    <li>
                        <a href="/history.php">About</a>
                    </li>
                    <li>
                        <a href="/contact.php">Contact</a>
                    </li>

                    <li>
                        <a href="/login.php">Login</a>
                    </li>
                </ul>
            </div>
        </div>
    </nav>

Estou configurando isso certo?

(Em uma nota não relacionada, mas possivelmente relacionada? Quando o menu se torna móvel, eu clico no botão do menu e ele é recolhido. Empurrá-lo novamente não o desfaz. Portanto, este problema, com o outro, ambos significam configuração de JavaScript incorreta possivelmente?)


3
Desde o tempo que trabalho com bootstrap, acho que Boostrap não dá conta, você tem que definir a classe ativa sozinho ... Se eu estiver errado, vou aprender muito com isso ...
BENARD Patrick

1
Bem, @TheLittlePig está correto, você precisa adicionar a activeclasse você mesmo quando seu aplicativo gerar o HTML.
DavidG 01 de

Respostas:


143

Você incluiu o arquivo Bootstrap js minimizado e os plug-ins de recolhimento / transição enquanto os documentos afirmam que:

Ambos bootstrap.js e bootstrap.min.js contêm todos os plug-ins em um único arquivo.
Inclua apenas um.

e

Para efeitos de transição simples, inclua transição.js uma vez ao lado dos outros arquivos JS. Se você estiver usando bootstrap.js compilado (ou reduzido), não há necessidade de incluí-lo - ele já está lá.

Então esse pode muito bem ser o seu problema para minimizar o problema.

Para a classe ativa, você mesmo precisa administrar, mas é apenas uma ou duas linhas.

Bootstrap 3:

$(".nav a").on("click", function(){
   $(".nav").find(".active").removeClass("active");
   $(this).parent().addClass("active");
});

Bootply: http://www.bootply.com/IsRfOyf0f9

Bootstrap 4:

$(".nav .nav-link").on("click", function(){
   $(".nav").find(".active").removeClass("active");
   $(this).addClass("active");
});

2
Isso funciona se você passar de uma página para outra href(sem hash, mas enviar outra solicitação)?
Blaszard

1
@Blaszard em aplicativos / sites de página não única, você deve ter activeaula sobre o navitem por padrão.
Pete TNT

Nao funciona para mim. O item da lista nunca aparece como ativo !? O que eu não estou fazendo que vocês estão fazendo?
user465342

4
não está funcionando para mim, está sendo adicionado, mas no próximo segundo vai para a classe ativa inicial, então não vai ficar na página, por favor, alguém ajude nisso
sourav78611

11
@Pete TNT - Ainda não está claro e é muito frustrante quando as pessoas dão 90% de uma solução e assumem que todos sabem como aplicar os 10% restantes. Especialmente em cenários em que a sintaxe é difícil de acertar.
Dave

100

Aqui estava minha solução para alternar páginas ativas

$(document).ready(function() {
  $('li.active').removeClass('active');
  $('a[href="' + location.pathname + '"]').closest('li').addClass('active'); 
});

2
Onde devemos colocar isso? Desculpa; novo no JS: #
mrateb

2
Isso funciona bem no Bootstrap 4. @ Thomas8: deve ficar entre a tag <script>e </script> tags at the bottom of the html file before the </body> `(assumindo que você tenha tudo em um arquivo html).
alwaysCurious

adicionado o mesmo em site.js sem qualquer tag <script> e funcionou $ (document) .ready (function () {$ ('li.active'). removeClass ('active'); $ ('a [href = "'+ location.pathname +'"] '). mais próximo (' li '). addClass (' ativo ');});
Oracular Man

Para mim, esta foi a única solução que funcionou no bootstrap 3.3.7. Muito obrigado.
MitchellK

Essa solução acabou funcionando para mim. Eu adicionei na função: console.log (location.pathname) e percebi, no <a href='foo/bar>, eu perdi o último "/", se eu mudar para <a href = 'foo / bar / '>, então esta função funciona para tornar o "li" correto ativo na barra de navegação.
Emily

17

Isso funcionou perfeitamente para mim, porque "window.location.pathname" também contém dados antes do nome da página real, por exemplo, diretório / página.php. Portanto, o link da barra de navegação real só será definido como ativo se a url contiver esse link.

$(document).ready(function() {
    $.each($('#navbar').find('li'), function() {
        $(this).toggleClass('active', 
            window.location.pathname.indexOf($(this).find('a').attr('href')) > -1);
    }); 
});

5
todas as outras soluções não funcionam, exceto a sua, eu tentei uma por uma
Lynob

14

Com a versão 3.3.4 do bootstrap, em páginas html longas, você pode consultar as seções da pág. por classe ou id para gerenciar o link da barra de navegação ativa com spy-scroll com o elemento body:

  <body data-spy="scroll" data-target="spy-scroll-id">

O data-target será um div com id = "spy-scroll-id"

    <div id="spy-scroll-id" class="collapse navbar-collapse">
      <ul class="nav navbar-nav">
        <li class="active"><a href="#topContainer">Home</a></li>
        <li><a href="#details">About</a></li>
        <li><a href="#carousel-container">SlideShow</a></li>
      </ul>
    </div>

Isso deve ativar os links clicando sem nenhuma função javascript necessária e também ativará automaticamente cada link conforme você rola pelas seções vinculadas correspondentes da página, o que um js onclick () não irá.


1
Obrigado. Deve ser: data-target = "# spy-scroll-id" e não data-target = "spy-scroll-id"
Vdex

10

Tudo o que você precisa fazer é simplesmente adicionar data-toggle = "tab" ao seu link dentro da barra de navegação do bootstrap como este:

<ul class="nav navbar-nav">
  <li class="active"><a data-toggle="tab" href="#">Home</a></li>
  <li><a data-toggle="tab" href="#">Test</a></li>
  <li><a data-toggle="tab" href="#">Test2</a></li>
</ul>

isso é realmente útil, mas não funciona quando você tem uma segunda lista navbar-nav (normal) e também uma segunda lista navbar-direita. Você acaba com dois ativos que nunca são liberados
Karl P

5
quando adiciono "data-toggle", a página não pode ir para o "#place" especificado em href.
scorpiozj

Na verdade, uma atualização. Como @scorpiozj mencionado. Quando adicionado, o link em si não funciona
mrateb

9

Se você não usa links de âncora, pode usar algo assim:

$(document).ready(function () {
    $.each($('#navbar').find('li'), function() {
        $(this).toggleClass('active',
            '/' + $(this).find('a').attr('href') == window.location.pathname);
    });
});

6

Com o Bootstrap 4, você pode usar isto:

$(document).ready(function() {
    $(document).on('click', '.nav-item a', function (e) {
        $(this).parent().addClass('active').siblings().removeClass('active');
    });
});

Obrigado, não tenho ideia de por que os outros (Bootstrap 3) não funcionaram
information_interchange

4

Esta solução elegante funcionou para mim. Quaisquer novas ideias / sugestões são bem-vindas.

$( document ).on( 'click', '.nav-list li', function ( e ) {
    $( this ).addClass( 'active' ).siblings().removeClass( 'active' );
} );

Você pode usar o método "siblings ()" do jQuery para manter apenas o item acessado ativo e seus irmãos inativos.


3

Eu uso isso. É curto, elegante e fácil de entender.

$(document).ready(function() {
    $('a[href$="' + location.pathname + '"]').addClass('active');
});

2

Tenho lutado com isso hoje, a alternância de dados só funciona se estou em um aplicativo de página única.

Não estou usando ajax para carregar o conteúdo, na verdade estou fazendo uma solicitação de postagem para outras páginas, então o primeiro script js também foi inútil. Eu resolvo com estas linhas:

var active = window.location.pathname;
$(".nav a[href|='" + active + "']").parent().addClass("active");

1

Espero que isso ajude a resolver este problema.

      var navlnks = document.querySelectorAll(".nav a");
        Array.prototype.map.call(navlnks, function(item) {

            item.addEventListener("click", function(e) {

                var navlnks = document.querySelectorAll(".nav a"); 

                Array.prototype.map.call(navlnks, function(item) {

                    if (item.parentNode.className == "active" || item.parentNode.className == "active open" ) {

                        item.parentNode.className = "";

                    } 

                }); 

                e.currentTarget.parentNode.className = "active";
            });
        });

1

Eu tive alguma dor com isso, usando uma lista de itens gerada dinamicamente - WordPress Stack.

Adicionado isso e funcionou:

$(document).ready(function () {
    $(".current-menu-item").addClass("active");
});

Vai fazer isso na hora.


1

Estou procurando uma solução que eu possa usar no bootstrap 4 navbars e outros grupos de links.

Por uma razão ou outra, a maioria das soluções não funcionou, especialmente aquelas que tentam adicionar 'ativo' aos links onclick porque, é claro, uma vez que o link é clicado se o levar para outra página, então o 'ativo' adicionado não será lá porque o DOM mudou. Muitas das outras soluções não funcionaram porque geralmente não correspondiam ao link ou correspondiam a mais de um.

Esta solução elegante é adequada para links que são diferentes, ou seja: about.php, index.php, etc ...

$(function() {
   $('nav a[href^="' + location.pathname.split("/")[2] + '"]').addClass('active');
});

No entanto, quando se trata dos mesmos links com strings de consulta diferentes, como index.php? Tag = a, index.php? Tag = b, index.php? Tag = c, ele definirá todos eles como ativos, o que for clicado corresponder ao nome do caminho, não à consulta também.

Então eu tentei este código que combinava com o nome do caminho e a string de consulta e funcionou em todos os links com strings de consulta, mas quando um link como index.php foi clicado, ele também ativou os links de string de consulta semelhantes. Isso ocorre porque minha função está retornando uma string vazia se não houver uma string de consulta no link, novamente apenas correspondendo ao nome do caminho.

$(function() {
   $('nav a[href^="' + location.pathname.split("/")[2] + returnQueryString(location.href.split("?")[1]) + '"]').addClass('active');
});
/** returns a query string if there, else an empty string */
function returnQueryString (element) {
   if (element === undefined)
      return "";
   else
      return '?' + element;
}

Então, no final, abandonei essa rota, mantive-a simples e escrevi isso.

$('.navbar a').each(function(index, element) {
    //console.log(index+'-'+element.href);
    //console.log(location.href);
    /** look at each href in the navbar
      * if it matches the location.href then set active*/
    if (element.href === location.href){
        //console.log("---------MATCH ON "+index+" --------");
        $(element).addClass('active');
    }
});

Funciona em todos os links com ou sem strings de consulta porque element.href e location.href retornam o caminho completo. Para outros menus, etc, você pode simplesmente alterar o seletor de classe pai (navbar) por outro, por exemplo:

$('.footer a').each(function(index, element)...

Uma última coisa que também parece importante e essa é a biblioteca js & css que você está usando, mas talvez seja outro post. Espero que isso ajude e contribua.



0

Para abrir o menu do bootstrap móvel após clicar em um item, você pode usar isto

$("ul.nav.navbar-nav li a").click(function() {    

    $(".navbar-collapse").removeClass("in");
});

0

Estou usando o tema básico de bootstrap, aqui está o código de navbar de exemplo. Observe o nome da classe do elemento -> .nav - como é referido no java script.

/ Collect the nav links, forms, and other content for toggling
    #bs-example-navbar-collapse-1.collapse.navbar-collapse
      %ul.nav.navbar-nav
        %li
          %a{:href => "/demo/one"} Page One
        %li
          %a{:href => "/demo/two"} Page Two
        %li
          %a{:href => "/demo/three"} Page Three

na página de visualização (ou parcial) adicione: javascript, isso precisa ser executado toda vez que a página carrega.

haml view snippet ->

- content_for :javascript do
  :javascript
      $(function () {
          $.each($('.nav').find('li'), function() {
              $(this).toggleClass('active',
                  $(this).find('a').attr('href') == window.location.pathname);
          });
      });

No depurador javascript, certifique-se de que o valor do atributo 'href' corresponda a window.location.pathname. Isso é um pouco diferente da solução da @Zitrax, que me ajudou a corrigir meu problema.


0

Para AngularJS, você pode usar ng-classcom uma função como esta:

HTML ->

<nav class="navbar navbar-default" ng-controller="NavCtrl as vm">
  <div class="container">
    <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
      <ul class="nav navbar-nav" >
        <li ng-class="vm.Helper.UpdateTabActive('Home')"><a href="#" ng-click>Home</a></li>
        <li ng-class="vm.Helper.UpdateTabActive('About')"><a href="#about">About</a></li>
        <li ng-class="vm.Helper.UpdateTabActive('Contact')"><a href="#contact">Contact</a></li>        
      </ul>
    </div>
</nav>

E controlador

app.controller('NavCtrl', ['$scope', function($scope) {
    var vm = this;
    vm.Helper = {
        UpdateTabActive: function(sTab){
            return window.location.hash && window.location.hash.toLowerCase() == ("#/" + sTab).toLowerCase() ? 'active' : '';
        }
    }    
}]);

Se você estiver usando $ location, não haverá hash. Portanto, você pode extrair a string necessária do URL usando $ location

A seguir não funcionará em todos os casos ->

Usar uma variável de escopo como a seguir funcionará apenas quando clicada, mas se a transição for feita usando $state.transitionToou window.location ou atualizando manualmente o URL, o valor da guia não será atualizado

<ul class="nav navbar-nav" ng-init="Tab='Home'">
   <li ng-class="Tab == 'Home' ? 'active' : ''"><a href="#" ng-click="Tab = 'Home'">Home</a></li>
   <li ng-class="Tab == 'About' ? 'active' : ''"><a href="#" ng-click="Tab = 'About'">About</a></li>
</ul>

0

Adicione este JavaScript em seu arquivo js principal.

$(".navbar a").on("click", function(){
      $(".navbar").find(".active").removeClass("active");
      $(this).parent().addClass("active");
    });

3
Adicione a descrição da solução.
sg7

0

Tive que dar um passo à frente porque os nomes dos meus arquivos não eram iguais aos títulos da minha barra de navegação. ou seja, meu primeiro link da barra de navegação foi HOME, mas o nome do arquivo é índice ..

Portanto, basta pegar o nome do caminho e combiná-lo.

Obviamente, este é um exemplo bruto e poderia ser mais eficiente, mas é uma necessidade altamente personalizada.

var loc_path = location.pathname;
$('li.active').removeClass('active');



if(loc_path.includes('index')){
    $('li :eq(0)').addClass('active');
}else if(loc_path.includes('blog')){
    $('li :eq(2)').addClass('active');
}else if(loc_path.includes('news')){
    $('li :eq(3)').addClass('active');
}else if(loc_path.includes('house')){
    $('li :eq(4)').addClass('active');
}

0

Solução Bootstrap 4 que funcionou para mim:

$(document).ready(function() {
//You can name this function anything you like
function activePage(){
//When user lands on your website location.pathname is equal to "/" and in 
//that case it will add "active" class to all links
//Therefore we are going to remove first character "/" from the pathname
  var currentPage = location.pathname;
  var slicedCurrentPage = currentPage.slice(1);
//This will add active class to link for current page
  $('.nav-link').removeClass('active');
  $('a[href*="' + location.pathname + '"]').closest('li').addClass('active');
//This will add active class to link for index page when user lands on your website
     if (location.pathname == "/") {
         $('a[href*="index"]').closest('li').addClass('active');
    }
}
//Invoke function
activePage();
});

Isso só funcionará se href contiver location.pathname !

Se você está testando seu site em seu próprio PC (usando wamp, xampp, lamp, etc ...) e seu site está localizado em alguma subpasta, então seu caminho é na verdade "/algumapasta/algo.php", então não pegue confuso.

Se você não tiver certeza de usar o código a seguir, sugiro que você tenha certeza de qual é o local correto. Nome do caminho :

$(document).ready(function() {
  alert(location.pathname);
});

0

a próxima resposta é para aqueles que têm um menu de vários níveis:

var url = window.location.href;

var els = document.querySelectorAll(".dropdown-menu a");
for (var i = 0, l = els.length; i < l; i++) {
    var el = els[i];
    if (el.href === url) {
       el.classList.add("active");
       var parent = el.closest(".main-nav"); // add this class for the top level "li" to get easy the parent
       parent.classList.add("active");
    }
}

Exemplo de como funciona


0

Como alguém que não conhece javascript, aqui está um método PHP que funciona para mim e é fácil de entender. Minha barra de navegação inteira está em uma função PHP que está em um arquivo de componentes comuns que incluo em minhas páginas. Por exemplo, na minha página 'index.php' eu tenho ... `

<?php
   $calling_file = basename(__FILE__);
   include 'my_common_includes.php';    // Going to use my navbar function "my_navbar"
   my_navbar($calling_file);    // Call the navbar function
 ?>

Então no 'my_common_includes.php' eu tenho ...

<?php
   function my_navbar($calling_file)
   {
      // All your usual nabvbar code here up to the menu items
      if ($calling_file=="index.php")   {   echo '<li class="nav-item active">';    } else {    echo '<li class="nav-item">';   }
    echo '<a class="nav-link" href="index.php">Home</a>
</li>';
      if ($calling_file=="about.php")   {   echo '<li class="nav-item active">';    } else {    echo '<li class="nav-item">';   }
    echo '<a class="nav-link" href="about.php">About</a>
</li>';
      if ($calling_file=="galleries.php")   {   echo '<li class="nav-item active">';    } else {    echo '<li class="nav-item">';   }
    echo '<a class="nav-link" href="galleries.php">Galleries</a>
</li>';
       // etc for the rest of the menu items and closing out the navbar
     }
  ?>

0

O Bootstrap 4 requer que você direcione o liitem para classes ativas. Para fazer isso, você precisa encontrar o pai do a. O 'hitbox' do aé tão grande quanto o, limas devido ao borbulhar do evento em JS, ele devolverá o aevento. Portanto, você deve adicioná-lo manualmente ao seu pai.

  //set active navigation after click
  $(".nav-link").on("click", (event) => {
    $(".navbar-nav").find(".active").removeClass('active');
    $(event.target).parent().addClass('active');
  });

0

Tentei cerca de 5 primeiras soluções e diferentes variações delas, mas não funcionaram para mim.

Finalmente consegui trabalhar com essas duas funções.

$(document).on('click', '.nav-link', function () {
    $(".nav-item").find(".active").removeClass("active");
})

$(document).ready(function() {
    $('a[href="' + location.pathname + '"]').closest('.nav-item').addClass('active'); 
});

0

ao usar header.php para cada página do código navbar, o jquery não funciona, o ativo é aplicado e depois removido, uma solução simples é a seguinte

em cada variável definida de página <?php $pageName = "index"; ?>na página de índice e da mesma forma <?php $pageName = "contact"; ?>na página de contato

em seguida, chame header.php (ou seja, o código de navegação está em header.php) <?php include('header.php'); >

no header.php certifique-se de que cada link de navegação é o seguinte

<a class="nav-link <?php if ($page_name == 'index') {echo "active";} ?> href="index.php">Home</a>

<a class="nav-link <?php if ($page_name == 'contact') {echo "active";} ?> href="contact.php">Contact Us</a>

espero que isso ajude, porque eu gastei dias para fazer o jquery funcionar, mas falhou,

se alguém pudesse explicar qual é exatamente o problema quando o header.php é incluído e a página carrega ... por que o jquery não consegue adicionar a classe ativa ao link nav .. ??


-1
$(document).ready(function() {
            
   var url = window.location.href;
            
   $('a[href*="'+url+'"]').addClass("active");
            
});
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.