Bootstrap navbar Active State funktioniert nicht


85

Ich habe Bootstrap v3.

Ich benutze das class="active"auf meinem navbarund es schaltet nicht, wenn ich Menüpunkte drücke. Ich weiß, wie man das macht jQueryund eine Klickfunktion erstellt, aber ich denke, diese Funktionalität sollte in Bootstrap enthalten sein? Vielleicht handelt es sich also um ein JavaScript-Problem?

Hier ist mein Header mit meinen js / css / bootstrap-Dateien, die ich aufgenommen habe:

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

Hier ist mein 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>

Richte ich das richtig ein?

(Nicht verwandt, aber möglicherweise verwandt? Wenn das Menü mobil wird, klicke ich auf die Menüschaltfläche und es wird ausgeblendet. Wenn Sie es erneut drücken, wird es jedoch nicht wieder ausgeklappt. Dieses Problem mit dem anderen bedeutet also ein falsches JavaScript-Setup vielleicht?)


3
Da ich mit Bootstrap arbeite, denke ich, dass Boostrap es nicht schafft, müssen Sie die aktive Klasse selbst festlegen ... Wenn ich mich irre, werde ich viel damit lernen ...
BENARD Patrick

1
Nun, @TheLittlePig ist korrekt. Sie müssen die activeKlasse selbst hinzufügen, wenn Ihre Anwendung den HTML- Code generiert.
DavidG

Antworten:


142

Sie haben die minimierte Bootstrap-JS-Datei und die Plugins zum Reduzieren / Übergang eingefügt, während in den Dokumenten Folgendes angegeben ist:

Sowohl bootstrap.js als auch bootstrap.min.js enthalten alle Plugins in einer einzigen Datei.
Schließen Sie nur eine ein.

und

Fügen Sie für einfache Übergangseffekte Transition.js einmal neben den anderen JS-Dateien ein. Wenn Sie die kompilierte (oder minimierte) bootstrap.js verwenden, müssen Sie diese nicht einschließen - sie ist bereits vorhanden.

Das könnte also Ihr Problem für das Minimierungsproblem sein.

Für die aktive Klasse müssen Sie es selbst verwalten, aber es sind nur ein oder zwei Zeilen.

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
Funktioniert dies, wenn Sie von der Seite zu einer anderen wechseln href(kein Hash, sondern eine andere Anfrage senden)?
Blaszard

1
@Blaszard In Apps / Sites, die keine einzelne Seite haben, sollte activedas navElement standardmäßig eine Klasse haben .
Pete TNT

Funktioniert bei mir nicht Das Listenelement wird nie als aktiv angezeigt!? Was mache ich nicht, was ihr macht?
user465342

4
Es funktioniert nicht für mich, es wird hinzugefügt, aber in der nächsten Sekunde geht es in die erste aktive Klasse, so dass es nicht auf der Seite bleibt. Bitte helfen Sie jemandem dabei
Sourav78611

9
@Pete TNT - Es ist immer noch nicht klar und es ist sehr frustrierend, wenn Leute 90% einer Lösung geben und davon ausgehen, dass jeder weiß, wie man die restlichen 10% anwendet. Besonders in Szenarien, in denen die Syntax schwer zu verstehen ist.
Dave

90

Hier war meine Lösung zum Wechseln aktiver Seiten

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

2
Wo sollen wir das hinstellen? Es tut uns leid; neu bei JS: #
mrateb

2
Dies funktioniert gut in Bootstrap 4. @ Thomas8: Dies sollte zwischen <script>und </script> tags at the bottom of the html file before the </ body> `tag liegen (vorausgesetzt, Sie haben alles in einer HTML-Datei).
alwaysCurious

fügte das gleiche in site.js ohne <script> -Tag hinzu und es funktionierte $ (document) .ready (function () {$ ('li.active'). removeClass ('active'); $ ('a [href = "'+ location.pathname +'"] '). am nächsten (' li '). addClass (' active ');});
Oracular Man

Für mich war dies die einzige Lösung, die auf Bootstrap 3.3.7 funktioniert hat. Vielen Dank.
MitchellK

Diese Lösung hat schließlich für mich funktioniert. Ich habe in der Funktion: console.log (location.pathname) hinzugefügt und festgestellt, dass ich in der <a href='foo/bar> das letzte "/" verpasst habe, wenn ich zu <a href = 'foo / bar / wechsle. '>, dann funktioniert diese Funktion, um das richtige "li" auf der Navigationsleiste zu aktivieren.
Emily

16

Dies hat bei mir perfekt funktioniert, da "window.location.pathname" auch Daten vor dem tatsächlichen Seitennamen enthält, z. B. directory / page.php. Der eigentliche Navbar-Link wird also nur aktiviert, wenn die URL diesen Link enthält.

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

5
Alle anderen Lösungen außer Ihren funktionieren nicht. Ich habe sie
einzeln

14

Mit der Version 3.3.4 von Bootstrap können Sie auf langen HTML-Seiten auf Abschnitte der Seite verweisen. nach Klasse oder ID, um den aktiven Navigationsleisten-Link mit Spy-Scroll mit dem Body-Element zu verwalten:

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

Das Datenziel ist ein Div mit der 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>

Dies sollte Links aktivieren, indem Sie auf klicken, ohne dass Javascript-Funktionen erforderlich sind, und wird automatisch jeden Link aktivieren, wenn Sie durch die entsprechenden verknüpften Abschnitte der Seite scrollen, was ein js onclick () nicht tut.


1
Vielen Dank. Es sollte sein: data-target = "# spy-scroll-id" und nicht data-target = "spy-scroll-id"
Vdex

10

Alles, was Sie tun müssen, ist einfach data-toggle = "tab" zu Ihrem Link in der Bootstrap-Navigationsleiste hinzuzufügen:

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

das ist wirklich nützlich, aber es funktioniert nicht, wenn Sie eine navbar-nav (normal) und haben auch eine navbar rechten zweiten Liste. Sie haben zwei aktive, die nie gelöscht wurden
Karl P

4
Wenn ich "data-toggle" hinzufüge, kann die Seite nicht zu dem in href angegebenen "#place" wechseln.
Scorpiozj

Eigentlich ein Update. Wie @scorpiozj erwähnt. Wenn dies hinzugefügt wird, funktioniert der Link selbst nicht
mrateb

9

Wenn Sie keine Ankerlinks verwenden, können Sie Folgendes verwenden:

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

5

Mit Bootstrap 4 können Sie Folgendes verwenden:

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

Danke, keine Ahnung, warum die anderen (Bootstrap 3) nicht funktionierten
information_interchange

4

Diese elegante Lösung hat den Trick für mich getan. Neue Ideen / Vorschläge sind willkommen.

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

Sie können die "Geschwister ()" - Methode von jQuery verwenden, um nur das Element, auf das zugegriffen wird, aktiv und seine Geschwister inaktiv zu halten.


2

Ich habe heute damit zu kämpfen, Data-Tgle hat nur funktioniert, wenn ich auf einer einzelnen Seite arbeite.

Ich verwende Ajax nicht, um den Inhalt zu laden, den ich tatsächlich für andere Seiten poste, sodass das erste JS-Skript ebenfalls nutzlos war. Ich löse es mit diesen Zeilen:

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

1

Ich hoffe, dies wird helfen, dieses Problem zu lösen.

      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

Ich hatte einige Probleme damit, einen dynamisch generierten Listeneintrag zu verwenden - WordPress Stack.

Fügte dies hinzu und es funktionierte:

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

Wird es im laufenden Betrieb tun.


1

Ich benutze das. Es ist kurz, elegant und leicht zu verstehen.

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


0

Wenn Sie das Bootstrap-Menü für Mobilgeräte nach dem Klicken auf ein Element deaktivieren möchten, können Sie es verwenden

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

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

0

Ich verwende das nackte Bootstrap-Thema. Hier ist der Beispiel-Navigationscode. Beachten Sie den Klassennamen des Elements -> .nav -, auf den im Java-Skript verwiesen wird.

/ 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

Fügen Sie auf der Ansichtsseite (oder teilweise) Folgendes hinzu: Javascript, dies muss jedes Mal ausgeführt werden, wenn die Seite geladen wird.

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

Stellen Sie im Javascript-Debugger sicher, dass der Wert des Attributs 'href' mit window.location.pathname übereinstimmt. Dies unterscheidet sich geringfügig von der Lösung von @Zitrax, mit der ich mein Problem beheben konnte.


0

Für AngularJSkönnen Sie ng-classmit einer Funktion wie dieser verwenden:

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>

Und Controller

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

Wenn Sie $ location verwenden, gibt es keinen Hash. Sie können also die erforderliche Zeichenfolge mithilfe von $ location aus der URL extrahieren

Folgendes funktioniert nicht in allen Fällen ->

Die Verwendung einer Bereichsvariablen wie der folgenden funktioniert nur, wenn Sie darauf $state.transitionToklicken. Wenn der Übergang jedoch mit oder window.location oder manuellem Aktualisieren der URL erfolgt, wird der Tab-Wert nicht aktualisiert

<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

Fügen Sie dieses JavaScript zu Ihrer Haupt-JS-Datei hinzu.

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

3
Bitte fügen Sie die Beschreibung der Lösung hinzu.
SG7

0

Ich musste einen Schritt nach vorne machen, weil meine Dateinamen nicht mit meinen Navigationsleisten-Titeln übereinstimmten. dh mein erster Navigationsleisten-Link war HOME, aber der Dateiname ist index ..

Also schnapp dir einfach den Pfadnamen und passe ihn an.

Offensichtlich ist dies ein grobes Beispiel und könnte effizienter sein, aber es ist ein sehr kundenspezifischer Bedarf.

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

Bootstrap 4-Lösung, die für mich funktioniert hat:

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

Dies funktioniert nur, wenn href location.pathname enthält !

Wenn Sie Ihre Site auf Ihrem eigenen PC testen (mit wamp, xampp, lamp usw.) und sich Ihre Site in einem Unterordner befindet, lautet Ihr Pfad tatsächlich "/somefolder/something.php" verwirrt.

Ich würde vorschlagen, wenn Sie nicht sicher sind, folgenden Code zu verwenden, damit Sie sicherstellen können, dass der richtige location.pathname lautet :

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

0

Die nächste Antwort ist für diejenigen, die ein mehrstufiges Menü haben:

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

Beispiel, wie es funktioniert


0

Als jemand, der kein Javascript kennt, ist hier eine PHP-Methode, die für mich funktioniert und leicht zu verstehen ist. Meine gesamte Navigationsleiste befindet sich in einer PHP-Funktion, die sich in einer Datei mit allgemeinen Komponenten befindet, die ich von meinen Seiten einbinde. So habe ich zum Beispiel auf meiner 'index.php'-Seite ... `

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

Dann habe ich in der 'my_common_includes.php' ...

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

Für Bootstrap 4 müssen Sie das liElement auf aktive Klassen ausrichten. Dazu müssen Sie das Elternteil des finden a. Die 'Hitbox' von aist so groß wie die, liaber aufgrund des sprudelnden Ereignisses in JS erhalten Sie das aEreignis zurück. Sie müssen es also manuell zu seinem übergeordneten Element hinzufügen.

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

0

Ich habe ungefähr die ersten 5 Lösungen und verschiedene Variationen davon ausprobiert, aber sie haben bei mir nicht funktioniert.

Endlich habe ich es mit diesen beiden Funktionen zum Laufen gebracht.

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

Wenn Sie header.php für jede Seite für den Navigationscode verwenden, funktioniert die Abfrage nicht, die aktive wird angewendet und dann entfernt. Eine einfache Lösung lautet wie folgt

auf jeder Seite Variable <?php $pageName = "index"; ?>auf Indexseite und ähnlich <?php $pageName = "contact"; ?>auf Kontaktseite setzen

Rufen Sie dann die Datei header.php auf (dh der Navigationscode befindet sich in der Datei header.php). <?php include('header.php'); >

Stellen Sie in der header.php sicher, dass jeder Navi-Link wie folgt ist

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

Ich hoffe, das hilft, weil ich Tage damit verbracht habe, die Abfrage zum Laufen zu bringen, aber gescheitert bin.

Wenn jemand freundlich erklären würde, was genau das Problem ist, wenn die header.php enthalten ist und dann die Seite geladen wird ... warum kann die jquery die aktive Klasse nicht zum nav-link hinzufügen .. ??


0

Ich habe nach einer Lösung gesucht, die ich für Bootstrap 4-Navigationsleisten und andere Gruppen von Links verwenden kann.

Aus dem einen oder anderen Grund haben die meisten Lösungen nicht funktioniert, insbesondere diejenigen, die versuchen, Links per Mausklick "aktiv" hinzuzufügen, da natürlich das von Ihnen hinzugefügte "aktiv" nicht angezeigt wird, wenn Sie auf den Link klicken, wenn Sie zu einer anderen Seite gelangen dort, weil sich das DOM geändert hat. Viele der anderen Lösungen funktionierten auch nicht, weil sie oft nicht mit dem Link übereinstimmten oder mit mehr als einer übereinstimmten.

Diese elegante Lösung eignet sich für Links, die unterschiedlich sind, z. B.: About.php, index.php usw.

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

Wenn es jedoch zu denselben Links mit unterschiedlichen Abfragezeichenfolgen wie index.php? Tag = a, index.php? Tag = b, index.php? Tag = c kam, wurden alle auf aktiv gesetzt, je nachdem, auf was geklickt wurde passend zum Pfadnamen nicht auch zur Abfrage.

Also habe ich diesen Code ausprobiert, der mit dem Pfadnamen und der Abfragezeichenfolge übereinstimmt, und er hat bei allen Links mit Abfragezeichenfolgen funktioniert, aber wenn auf einen Link wie index.php geklickt wurde, wurden auch die ähnlichen Links für Abfragezeichenfolgen aktiviert. Dies liegt daran, dass meine Funktion eine leere Zeichenfolge zurückgibt, wenn der Link keine Abfragezeichenfolge enthält, die wiederum nur mit dem Pfadnamen übereinstimmt.

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

Am Ende habe ich diese Route aufgegeben und sie einfach gehalten und geschrieben.

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

Es funktioniert für alle Links mit oder ohne Abfragezeichenfolgen, da element.href und location.href beide den vollständigen Pfad zurückgeben. Für andere Menüs usw. können Sie einfach die übergeordnete Klassenauswahl (Navigationsleiste) für eine andere ändern, dh:

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

Eine letzte Sache, die ebenfalls wichtig erscheint und die von Ihnen verwendete js & css-Bibliothek ist, aber das ist vielleicht ein anderer Beitrag. Ich hoffe das hilft und trägt dazu bei.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.