El estado activo de la barra de navegación de Bootstrap no funciona

91

Tengo bootstrap v3.

Utilizo el class="active"en mi navbary no cambia cuando presiono elementos del menú. Sé cómo hacer esto jQueryy crear una función de clic, pero creo que esta funcionalidad debería incluirse en el arranque. Entonces, ¿tal vez sea un problema de JavaScript?

Aquí está mi encabezado con mis archivos js / css / bootstrap que he incluido:

<!-- 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>

Aquí está mi 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>

¿Estoy configurando esto bien?

(En una nota no relacionada, pero ¿posiblemente relacionada? Cuando el menú se vuelve móvil, hago clic en el botón de menú y se colapsa. Sin embargo, presionarlo nuevamente no lo deshace. Por lo tanto, este problema, con el otro, significan una configuración incorrecta de JavaScript ¿quizás?)

TheLettuceMaster
fuente
3
Desde que trabajo con bootstrap, creo que Boostrap no lo maneja, tienes que establecer una clase activa tú mismo ... Si me equivoco, aprenderé mucho con ella ...
BENARD Patrick
1
Bueno, @TheLittlePig es correcto, debe agregar la activeclase usted mismo cuando su aplicación genera el HTML.
DavidG

Respuestas:

143

Ha incluido el archivo Bootstrap js minificado y los complementos de contracción / transición, mientras que los documentos indican que:

Tanto bootstrap.js como bootstrap.min.js contienen todos los complementos en un solo archivo.
Incluya solo uno.

y

Para efectos de transición simples, incluya transición.js una vez junto con los otros archivos JS. Si está utilizando bootstrap.js compilado (o minimizado), no es necesario incluirlo, ya está allí.

Entonces ese bien podría ser su problema para minimizar el problema.

Para la clase activa, debe administrarlo usted mismo, pero es solo una línea o dos.

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");
});
Pete TNT
fuente
2
¿Funciona esto si te mueves de la página a otra en href(no hash pero envías otra solicitud)?
Blaszard
1
@Blaszard en aplicaciones / sitios que no sean de una sola página, debe tener activeclase en el navelemento de forma predeterminada.
Pete TNT
No me funciona. ¿El elemento de la lista nunca aparece como activo? ¿Qué no estoy haciendo que ustedes estén haciendo?
user465342
4
no está funcionando para mí, se está agregando, pero en el próximo segundo va a la clase activa inicial, por lo que no se queda en la página, por favor, alguien ayude en esto
sourav78611
9
@Pete TNT - Todavía no está claro y es muy frustrante cuando la gente da el 90% de una solución y asume que todos saben cómo aplicar el 10% restante. Especialmente en escenarios donde la sintaxis es difícil de acertar.
Dave
97

Aquí estaba mi solución para cambiar de páginas activas

$(document).ready(function() {
  $('li.active').removeClass('active');
  $('a[href="' + location.pathname + '"]').closest('li').addClass('active'); 
});
Jon
fuente
2
¿Dónde deberíamos poner esto? Lo siento; nuevo en JS: #
mrateb
2
Esto funciona bien en Bootstrap 4. @ Thomas8: esto debe ir entre <script>y </script> tags at the bottom of the html file before the </ body> etiqueta `(suponiendo que tiene todo en un archivo html).
alwaysCurious
agregó lo mismo en site.js sin ninguna etiqueta <script> y funcionó $ (document) .ready (function () {$ ('li.active'). removeClass ('active'); $ ('a [href = "'+ location.pathname +'"] '). más cercano (' li '). addClass (' activo ');});
Oracular Man
Para mí, esta fue la única solución que funcionó en bootstrap 3.3.7 muchas gracias.
MitchellK
Esta solución finalmente funcionó para mí. Agregué en la función: console.log (location.pathname) y me di cuenta, en <a href='foo/bar>, me perdí el último "/", si cambio a <a href = 'foo / bar / '>, entonces esta función funciona para activar el "li" correcto en la barra de navegación.
Emily
16

Esto funcionó perfectamente para mí, porque "window.location.pathname" también contiene datos antes del nombre real de la página, por ejemplo, directorio / page.php. Por lo tanto, el enlace de la barra de navegación real solo se establecerá como activo si la URL contiene este enlace.

$(document).ready(function() {
    $.each($('#navbar').find('li'), function() {
        $(this).toggleClass('active', 
            window.location.pathname.indexOf($(this).find('a').attr('href')) > -1);
    }); 
});
Bettelbursche
fuente
5
todas las demás soluciones no funcionan excepto la suya, las probé una por una
Lynob
14

Con la versión 3.3.4 de bootstrap, en las páginas html largas puede consultar las secciones de la pág. por clase o identificación para administrar el enlace activo de la barra de navegación con desplazamiento espía con el elemento del cuerpo:

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

El objetivo de datos será un div con 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>

Esto debería activar los enlaces haciendo clic sin ninguna función de JavaScript necesaria y también activará automáticamente cada enlace a medida que se desplaza por las secciones vinculadas correspondientes de la página, lo que no hará un js onclick ().

Jim
fuente
1
Gracias. Debe ser: data-target = "# spy-scroll-id" y no data-target = "spy-scroll-id"
Vdex
10

Todo lo que necesita hacer es simplemente agregar data-toggle = "tab" a su enlace dentro de la barra de navegación de arranque de esta manera:

<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>
Hakan Fıstık
fuente
esto es realmente útil, pero no funciona cuando tiene una barra de navegación-navegación (normal) y también una segunda lista de la barra de navegación derecha. Terminas con dos activos que nunca se autorizan
Karl P
5
cuando agrego "alternancia de datos", la página no puede ir al "#lugar" especificado en href.
scorpiozj
En realidad, una actualización. Como mencionó @scorpiozj. Cuando se agrega esto, el enlace en sí no funciona
mrateb
9

Si no usa enlaces de anclaje, puede usar algo como esto:

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

Con Bootstrap 4 puedes usar esto:

$(document).ready(function() {
    $(document).on('click', '.nav-item a', function (e) {
        $(this).parent().addClass('active').siblings().removeClass('active');
    });
});
Carlos Cuesta
fuente
Gracias, no tengo idea de por qué los otros (Bootstrap 3) no funcionaron
information_interchange
4

Esta elegante solución me sirvió. Cualquier nueva idea / sugerencia es bienvenida.

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

Puede utilizar el método "siblings ()" de jQuery para mantener activo únicamente el elemento accedido y sus hermanos inactivos.

JefferinJoseph
fuente
2

He estado luchando con esto hoy, la alternancia de datos solo funcionaba si estoy en una aplicación de una sola página.

No estoy usando ajax para cargar el contenido, en realidad estoy haciendo una solicitud de publicación para otras páginas, por lo que el primer script js también fue inútil. Lo resuelvo con estas líneas:

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

Espero que esto ayude 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";
            });
        });
Kirill Shur
fuente
1

Tuve algo de dolor con esto, usando elementos de lista generados dinámicamente: WordPress Stack.

Agregó esto y funcionó:

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

Lo haré sobre la marcha.

Someguywhocodes
fuente
1

Yo uso esto. Es breve, elegante y fácil de entender.

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

Para desbloquear el menú móvil de bootstrap después de hacer clic en un elemento, puede usar esto

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

    $(".navbar-collapse").removeClass("in");
});
Nurul Amin
fuente
0

Estoy usando el tema bootstrap bare, aquí está el código de barra de navegación de muestra. Tenga en cuenta el nombre de clase del elemento -> .nav - ya que se hace referencia a esto en el script java.

/ 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

en la página de vista (o parcial) agregue esto: javascript, esto debe ejecutarse cada vez que se carga la página.

fragmento de vista haml ->

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

En el depurador de JavaScript, asegúrese de que el valor del atributo 'href' coincida con window.location.pathname. Esto es ligeramente diferente a la solución de @Zitrax que me ayudó a solucionar mi problema.

Rishi
fuente
0

Para AngularJS, puede usar ng-classcon una función 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>

Y 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' : '';
        }
    }    
}]);

Si está usando $ location, entonces no habrá hash. Para que pueda extraer la cadena requerida de la URL usando $ location

Lo siguiente no funcionará en todos los casos ->

El uso de una variable de alcance como la siguiente funcionará solo cuando se haga clic, pero si la transición se realiza usando $state.transitionToo window.location o actualizando manualmente la URL, el valor de la pestaña no se actualizará

<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>
Mahesh
fuente
0

Agregue este JavaScript en su archivo js principal.

$(".navbar a").on("click", function(){
      $(".navbar").find(".active").removeClass("active");
      $(this).parent().addClass("active");
    });
Md. Abunaser Khan
fuente
3
Agrega la descripción de la solución.
sg7
0

Tuve que dar un paso adelante porque los nombres de mis archivos no eran los mismos que los títulos de la barra de navegación. es decir, mi primer enlace de la barra de navegación fue INICIO, pero el nombre del archivo es índice.

Así que solo toma el nombre de la ruta y combínalo.

Obviamente, este es un ejemplo burdo y podría ser más eficiente, pero es una necesidad muy 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');
}
Cparello
fuente
0

Solución Bootstrap 4 que funcionó para mí:

$(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();
});

¡Esto solo funcionará si href contiene location.pathname !

Si está probando su sitio en su propia PC (usando wamp, xampp, lamp, etc.) y su sitio está ubicado en alguna subcarpeta, entonces su ruta es en realidad "/algunocarpeta/algo.php", así que no obtenga confuso.

Sugeriría si no está seguro de usar el siguiente código para que pueda asegurarse de cuál es la ubicación correcta .

$(document).ready(function() {
  alert(location.pathname);
});
Luka Sh
fuente
0

la siguiente respuesta es para aquellos que tienen un menú de varios niveles:

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");
    }
}

Ejemplo de cómo funciona

futur1st
fuente
0

Como alguien que no conoce javascript, aquí hay un método PHP que me funciona y es fácil de entender. Toda mi barra de navegación está en una función PHP que está en un archivo de componentes comunes que incluyo de mis páginas. Entonces, por ejemplo, en mi página 'index.php' tengo ... `

<?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
 ?>

Luego, en 'my_common_includes.php' tengo ...

<?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
     }
  ?>
M61 Vulcano
fuente
0

Bootstrap 4 requiere que apuntes el liartículo a clases activas. Para hacer eso, debe encontrar el padre del a. El 'hitbox' del aes tan grande como el lipero debido a la propagación del evento en JS le devolverá el aevento. Entonces tienes que agregarlo manualmente a su padre.

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

Probé las primeras 5 soluciones y diferentes variaciones de ellas, pero no funcionaron para mí.

Finalmente lo hice funcionar con estas dos funciones.

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

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

cuando se usa header.php para cada página para el código de la barra de navegación, el jquery no funciona, el activo se aplica y luego se elimina, una solución simple es la siguiente

en cada variable de conjunto de páginas <?php $pageName = "index"; ?>en la página de índice y de manera similar <?php $pageName = "contact"; ?> en la página Contáctenos

luego llame al header.php (es decir, el código de navegación está en header.php) <?php include('header.php'); >

en header.php asegúrese de que cada enlace de navegación sea el siguiente

<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 esto ayude porque he pasado días para que jquery funcione pero fallé,

si alguien tuviera la amabilidad de explicar cuál es exactamente el problema cuando se incluye header.php y luego se carga la página ... ¿por qué jquery no puede agregar la clase activa al enlace de navegación .. ??

Srikanth Kamath
fuente
0

He estado buscando una solución que pueda usar en las barras de navegación de Bootstrap 4 y otros grupos de enlaces.

Por una razón u otra, la mayoría de las soluciones no funcionaron, especialmente las que intentan agregar 'activo' a los enlaces al hacer clic porque, por supuesto, una vez que se hace clic en el enlace, si lo lleva a otra página, entonces el 'activo' que agregó no será allí porque el DOM ha cambiado. Muchas de las otras soluciones no funcionaron porque a menudo no coincidían con el enlace o porque coincidían con más de una.

Esta elegante solución está bien para enlaces que son diferentes, es decir: about.php, index.php, etc ...

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

Sin embargo, cuando se trataba de los mismos enlaces con diferentes cadenas de consulta, como index.php? Tag = a, index.php? Tag = b, index.php? Tag = c, los configuraría a todos como activos, cualquiera que sea el que se haga clic en él. coincidir con el nombre de ruta, no con la consulta también.

Así que probé este código que coincidía con el nombre de ruta y la cadena de consulta y funcionó en todos los enlaces con cadenas de consulta, pero cuando se hacía clic en un enlace como index.php, también se activaban los enlaces de cadenas de consulta similares. Esto se debe a que mi función devuelve una cadena vacía si no hay una cadena de consulta en el enlace, nuevamente, solo coincide con el nombre de la ruta.

$(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;
}

Así que al final abandoné esta ruta y la mantuve simple y escribí esto.

$('.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 en todos los enlaces con o sin cadenas de consulta porque element.href y location.href devuelven la ruta completa. Para otros menús, etc., simplemente puede cambiar el selector de clase principal (barra de navegación) por otro, es decir:

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

Una última cosa que también parece importante y es la biblioteca js & css que está utilizando, sin embargo, quizás sea otra publicación. Espero que esto ayude y contribuya.

Steve Whitby
fuente