web-dev-qa-db-fra.com

Bootstrap navbar état actif ne fonctionne pas

J'ai bootstrap v3.

J'utilise le class="active" sur ma navbar et il ne change pas lorsque j'appuie sur des éléments de menu. Je sais comment faire cela avec jQuery et créer une fonction de clic, mais je pense que cette fonctionnalité devrait être incluse dans le bootstrap? Alors peut-être que c'est un problème de JavaScript?

Voici mon en-tête avec mes fichiers js/css/bootstrap que j'ai inclus:

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

Voici mon code navbar:

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

Est-ce que je prépare cela correctement?

(Sur une note indépendante, mais liée possible? Lorsque le menu devient mobile, je clique sur le bouton du menu et il s'effondrera. Le refouler à nouveau ne le réduira pas pour autant. Alors, ce problème, avec l'autre, signifie à tort Configuration JavaScript peut-être?)

69
KickingLettuce

Vous avez inclus le fichier js minstock Bootstrap et les plugins collapse/transition, tandis que la documentation indique que:

Bootstrap.js et bootstrap.min.js contiennent tous les plugins dans un seul fichier.
Inclure un seul.

et

Pour des effets de transition simples, incluez transition.js une fois à côté de les autres fichiers JS. Si vous utilisez le compilé (ou minified) bootstrap.js, il n’est pas nécessaire d’inclure ceci, il est déjà là.

Cela pourrait donc être votre problème pour le problème de minimisation. 

Pour la classe active, vous devez gérer vous-même, mais c'est juste une ligne ou deux.

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

Voici ma solution pour changer de page active

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

Avec la version 3.3.4 de bootstrap, sur de longues pages html, vous pouvez vous référer à des sections de la page. par classe ou id pour gérer le lien de barre de navigation actif avec spy-scroll avec l'élément body:

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

La cible de données sera un div avec l'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>

Cela devrait activer les liens en cliquant sur aucune des fonctions javascript nécessaires et activera également automatiquement chaque lien lorsque vous faites défiler les sections liées correspondantes de la page, ce que ne fera pas un js onclick ().

13
jim

Cela fonctionne parfaitement pour moi, car "window.location.pathname" contient également des données précédant le nom de page réel, par exemple. répertoire/page.php. Ainsi, le lien de barre de navigation ne sera activé que si l’URL contient ce lien.

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

Si vous n'utilisez pas de liens d'ancrage, vous pouvez utiliser quelque chose comme ceci:

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

Tout ce que vous avez à faire est simplement d’ajouter data-toggle = "tab" à votre lien dans la barre de navigation bootstrap comme ceci: 

<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>
8
user6410107

Avec Bootstrap 4, vous pouvez utiliser ceci:

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

Cette solution élégante a fait l'affaire pour moi. Toutes les nouvelles idées/suggestions sont les bienvenues.

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

Vous pouvez utiliser la méthode "siblings ()" de jQuery pour ne garder que l'élément consulté actif et ses frères et sœurs inactifs.

4
JefferinJoseph

J'ai eu du mal avec cela aujourd'hui, data-togle ne fonctionnait que si je suis sur une application d'une seule page. 

Je n'utilise pas ajax pour charger le contenu. En fait, je fais une demande de publication pour d'autres pages, de sorte que le premier script js était également inutile. Je le résous avec ces lignes:

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

J'avais quelques difficultés avec cela, en utilisant une liste d'éléments générés dynamiquement - WordPress Stack.

Ajouté ceci et cela a fonctionné: 

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

Va le faire à la volée.

1
Someguywhocodes

J'espère que cela aidera à résoudre ce problème.

      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
Kirill Shur

La solution Bootstrap 4 qui a fonctionné pour moi:

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

Cela ne fonctionnera que si href contient location.pathname !

Si vous testez votre site sur votre propre ordinateur (avec wamp, xampp, lampe, etc ...) et que votre site est situé dans un sous-dossier, votre chemin est en fait "/somefolder/something.php", alors ne récupérez pas confus.

Si vous n’êtes pas sûr d’utiliser le code suivant pour vous assurer que le correct location.pathname :

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

La classe "active" n'est pas gérée de suite avec bootstrap. Depuis que vous utilisez PHP, vous pouvez voir:

Comment ajouter class = 'active' au menu html avec php

pour vous aider avec une méthode d'automatisation la plupart du temps. 

0
Kritner

En tant que personne qui ne connaît pas le javascript, voici une méthode PHP qui fonctionne pour moi et qui est facile à comprendre. Toute ma barre de navigation est dans une fonction PHP qui se trouve dans un fichier de composants communs que j'inclus dans mes pages. Ainsi, par exemple, dans ma page "index.php", j'ai ...

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

Puis dans le fichier 'my_common_includes.php' j'ai ...

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

Bootstrap 4 nécessite que vous cibliez l'élément li pour les classes actives. Pour ce faire, vous devez trouver le parent du a. La 'hitbox' de la a est aussi grosse que la li mais, en raison du bouillonnement d'événement dans JS, elle vous rendra l'événement a. Vous devez donc l'ajouter manuellement à son parent.

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

J'utilise le thème nu bootstrap, voici l'exemple de code de barre de navigation. Notez le nom de classe de l'élément -> .nav - comme il est mentionné dans le 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

dans la page d'affichage (ou partielle), ajoutez ceci: javascript, ceci doit être exécuté à chaque chargement de page.

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

Dans le débogueur JavaScript, assurez-vous que la valeur de l'attribut 'href' correspond à window.location.pathname. Ceci est légèrement différent de la solution de @Zitrax qui m'a aidé à résoudre mon problème.

0
Rishi

Pour amorcer la réduction du menu mobile après avoir cliqué sur un élément, vous pouvez utiliser cette option. 

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

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

Ajoutez ce JavaScript sur votre fichier js principal.  

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

Pour AngularJS, vous pouvez utiliser ng-class avec une fonction comme celle-ci:

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>

Et contrôleur 

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 vous utilisez $ location, alors il n'y aura pas de hachage. Ainsi, vous pouvez extraire la chaîne requise de l'URL en utilisant $ location

Suivre ne fonctionnera pas dans tous les cas ->

L'utilisation d'une variable d'étendue comme celle-ci ne fonctionnera que si vous cliquez dessus, mais si la transition est effectuée à l'aide de $state.transitionTo ou window.location ou si vous mettez à jour manuellement l'URL, la valeur de l'onglet ne sera pas mise à jour.

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

J'ai dû faire un pas en avant parce que mes noms de fichiers n'étaient pas les mêmes que ceux de mes barres de navigation. c'est-à-dire que mon premier lien avec la barre de navigation était HOME, mais que le nom du fichier est index.

Alors, prenez le nom du chemin et faites-le correspondre.

Évidemment, ceci est un exemple rudimentaire et pourrait être plus efficace mais c’est un besoin hautement personnalisé.

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
Cparello

la réponse suivante est pour ceux qui ont un menu à plusieurs niveaux:

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

 Exeample how it works 

0
futur1st