L'état actif de la barre de navigation Bootstrap ne fonctionne pas


91

J'ai bootstrap v3.

J'utilise le class="active"sur mon navbaret il ne change pas lorsque j'appuie sur les éléments de menu. Je sais comment faire cela avec jQueryet créer une fonction de clic, mais je pense que cette fonctionnalité devrait être incluse dans le bootstrap? Alors peut-être est-ce un problème 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 navbarcode:

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

Suis-je en train de configurer cela correctement?

(Sur une note sans rapport, mais peut-être lié? Lorsque le menu devient mobile, je clique sur le bouton de menu et il se réduit. Si vous appuyez à nouveau dessus, cela ne le désactive pas. Donc, ce problème, avec l'autre, signifie que la configuration de JavaScript est incorrecte. peut-être?)


3
Depuis que je travaille avec le bootstrap, je pense que Boostrap ne le gère pas, vous devez définir une classe active vous-même ... Si je me trompe, j'apprendrai beaucoup avec ...
BENARD Patrick

1
Eh bien @TheLittlePig est correct, vous devez ajouter la activeclasse vous-même lorsque votre application génère le HTML.
DavidG

Réponses:


143

Vous avez inclus le fichier js Bootstrap minifié et les plugins de réduction / transition tandis que la documentation indique que:

Bootstrap.js et bootstrap.min.js contiennent tous les plugins dans un seul fichier.
N'incluez qu'un seul.

et

Pour des effets de transition simples, incluez une fois transition.js avec les autres fichiers JS. Si vous utilisez le fichier bootstrap.js compilé (ou minifié), il n'est pas nécessaire de l'inclure - il est déjà là.

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

Pour la classe active, vous devez la gérer vous-même, mais ce n'est qu'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");
});

2
Cela fonctionne-t-il si vous passez de la page à une autre href(pas de hachage mais envoyez une autre requête)?
Blaszard

1
@Blaszard dans des applications / sites de page non unique, vous devriez avoir une activeclasse sur l' navélément par défaut.
Pete TNT

Ça ne marche pas pour moi. L'élément de liste n'apparaît jamais comme actif !? Qu'est-ce que je ne fais pas que vous faites?
user465342

4
sa ne fonctionne pas pour moi, ça devient ajouté , mais dans la prochaine seconde sa va initiale classe active de sorte qu'il ne reste pas sur la page quelqu'un s'il vous plaît aide sur ce
sourav78611

9
@Pete TNT - Ce n'est toujours pas clair et c'est très frustrant quand les gens donnent 90% d'une solution et supposent que tout le monde sait comment appliquer les 10% restants. Surtout dans les scénarios où la syntaxe est difficile à obtenir.
Dave

97

Voici ma solution pour changer de page active

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

2
Où devrions-nous mettre cela? Pardon; nouveau sur JS: #
mrateb

2
Cela fonctionne bien dans Bootstrap 4. @ Thomas8: cela devrait aller entre <script>et </script> tags at the bottom of the html file before the </body> `balise (en supposant que vous ayez tout dans un seul fichier html).
alwaysCurious

ajouté la même chose dans site.js sans aucune balise <script> et cela a fonctionné $ (document) .ready (function () {$ ('li.active'). removeClass ('active'); $ ('a [href = "'+ location.pathname +'"] '). plus proche (' li '). addClass (' active ');});
Oracular Man

Pour moi, c'était la seule solution qui fonctionnait sur bootstrap 3.3.7 merci beaucoup.
MitchellK

Cette solution a finalement fonctionné pour moi. J'ai ajouté dans la fonction: console.log (location.pathname) et réalisé, dans le <a href='foo/bar>, j'ai manqué le dernier "/", si je change en <a href = 'foo / bar / '>, alors cette fonction fonctionne pour rendre le bon "li" actif sur la barre de navigation.
Emily

16

Cela a parfaitement fonctionné pour moi, car "window.location.pathname" contient également des données avant le vrai nom de la page, par exemple répertoire / page.php. Ainsi, le lien réel de la 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);
    }); 
});

5
toutes les autres solutions ne fonctionnent pas sauf la vôtre, je les ai essayées une par une
Lynob

14

Avec la version 3.3.4 de bootstrap, sur de longues pages html, vous pouvez vous référer aux sections du pg. par classe ou id pour gérer le lien actif de la barre de navigation 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 sans aucune fonction javascript nécessaire et activera également automatiquement chaque lien lorsque vous faites défiler les sections liées correspondantes de la page, ce qu'un js onclick () ne fera pas.


1
Merci. Il devrait être: data-target = "# spy-scroll-id" et non data-target = "spy-scroll-id"
Vdex

10

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>

c'est vraiment utile, mais cela ne fonctionne pas quand vous avez une barre de navigation-nav (normal) et aussi une deuxième liste de barre de navigation à droite. Vous vous retrouvez avec deux actifs qui ne sont jamais effacés
Karl P

5
quand j'ajoute "data-toggle", la page ne peut pas aller au "#place" spécifié dans href.
scorpiozj

En fait, une mise à jour. Comme @scorpiozj l'a mentionné. Lorsque cela est ajouté, le lien lui-même ne fonctionne pas
mrateb

9

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

6

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

Merci, aucune idée de la raison pour laquelle les autres (Bootstrap 3) n'ont pas fonctionné
information_interchange

4

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 garder uniquement l'élément accédé actif et ses frères inactifs.


2

J'ai eu du mal avec cela aujourd'hui, le basculement des données ne fonctionnait que si je suis sur une application d'une seule page.

Je n'utilise pas ajax pour charger le contenu.Je fais en fait une demande de publication pour d'autres pages, donc 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");

1

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

J'ai eu un peu de mal 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");
});

Je le ferai à la volée.


1

J'utilise ça. C'est court, élégant et facile à comprendre.

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


0

Pour le menu mobile bootstrap, un-collapse après avoir cliqué sur un élément, vous pouvez utiliser ceci

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

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

0

J'utilise le thème nu bootstrap, voici l'exemple de code de la barre de navigation. Notez le nom de classe de l'élément -> .nav - car il est référencé 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, cela doit être exécuté à chaque chargement de la page.

extrait de vue haml ->

- 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. C'est légèrement différent de la solution de @Zitrax qui m'a aidé à résoudre mon problème.


0

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

Le suivi ne fonctionnera pas dans tous les cas ->

L'utilisation d'une variable de portée comme celle-ci ne fonctionnera que si vous cliquez dessus, mais si la transition est effectuée en utilisant $state.transitionToou window.location ou en mettant à 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

Ajoutez ce JavaScript sur votre fichier js principal.

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

3
Veuillez ajouter la description de la solution.
sg7

0

J'ai dû faire un pas en avant car mes noms de fichiers n'étaient pas les mêmes que les titres de ma barre de navigation. c'est-à-dire que mon premier lien de barre de navigation était HOME mais le nom de fichier est index ..

Alors saisissez simplement le chemin et faites-le correspondre.

Évidemment, c'est un exemple grossier et pourrait être plus efficace, mais il s'agit d'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

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 PC (en utilisant wamp, xampp, lamp, etc ...) et que votre site se trouve dans un sous-dossier, votre chemin est en fait "/somefolder/something.php", alors n'obtenez pas confus.

Je suggérerais si vous n'êtes pas sûr d'utiliser le code suivant afin que vous puissiez vous assurer quel est le bon emplacement .

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

0

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

Exemple de fonctionnement


0

En tant que personne ne connaissant pas 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 à partir de mes pages. Donc 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
 ?>

Ensuite, dans le '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

Bootstrap 4 vous oblige à cibler l' liélément pour les classes actives. Pour ce faire, vous devez trouver le parent du a. La «hitbox» du aest aussi grande que la limais en raison du bouillonnement de l'événement dans JS, elle vous rendra l' aévénement. 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

J'ai essayé les 5 premières solutions et différentes variantes d'entre elles, mais elles n'ont pas fonctionné pour moi.

Enfin, je l'ai fait fonctionner avec ces deux fonctions.

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

lorsque vous utilisez header.php pour chaque page pour le code de la barre de navigation, la jquery ne fonctionne pas, l'actif est appliqué puis supprimé, une solution simple est la suivante

sur chaque variable d'ensemble de pages <?php $pageName = "index"; ?>sur la page Index et de même <?php $pageName = "contact"; ?>sur la page Contactez-nous

puis appelez header.php (c'est-à-dire que le code de navigation est dans header.php) <?php include('header.php'); >

dans le header.php, assurez-vous que chaque lien de navigation est comme suit

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

j'espère que cela aide car j'ai passé des jours à faire fonctionner la jquery mais j'ai échoué,

si quelqu'un voulait bien expliquer quel est exactement le problème lorsque l'en-tête.php est inclus et que la page se charge ... pourquoi la jquery ne parvient pas à ajouter la classe active au lien de navigation ... ??


0

J'ai cherché une solution que je peux utiliser sur bootstrap 4 navbars et d'autres groupes de liens.

Pour une raison ou une autre, la plupart des solutions n'ont pas fonctionné, en particulier celles qui essaient d'ajouter `` actif '' aux liens lors du clic car bien sûr, une fois que le lien est cliqué, s'il vous amène à une autre page, le `` actif '' que vous avez ajouté ne sera pas là parce que le DOM a changé. La plupart des autres solutions ne fonctionnaient pas parce qu'elles ne correspondaient souvent pas au lien ou qu'elles correspondaient à plus d'une.

Cette solution élégante convient parfaitement aux liens différents, c'est-à-dire about.php, index.php, etc ...

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

Cependant, quand il s'agissait des mêmes liens avec des chaînes de requête différentes telles que index.php? Tag = a, index.php? Tag = b, index.php? Tag = c, il les mettrait tous à actif, quel que soit le clic sur lequel il était correspondant au chemin et non à la requête

J'ai donc essayé ce code qui correspondait au chemin d'accès et à la chaîne de requête et cela fonctionnait sur tous les liens avec des chaînes de requête, mais lorsqu'un lien comme index.php était cliqué, il activait également les liens de chaîne de requête similaires. C'est parce que ma fonction renvoie une chaîne vide s'il n'y a pas de chaîne de requête dans le lien, encore une fois correspondant au chemin.

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

Donc, à la fin, j'ai abandonné cette route et je l'ai gardée simple et j'ai écrit ceci.

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

Il fonctionne sur tous les liens avec ou sans chaînes de requête car element.href et location.href renvoient tous deux le chemin complet. Pour d'autres menus, etc., vous pouvez simplement changer le sélecteur de classe parent (barre de navigation) pour un autre ie:

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

Une dernière chose qui semble également importante et c'est la bibliothèque js et css que vous utilisez, mais c'est peut-être un autre article. J'espère que cela aide et contribue.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.