Lo stato attivo della barra di navigazione Bootstrap non funziona


91

Ho bootstrap v3.

Uso il class="active"sul mio navbare non cambia quando premo le voci di menu. So come farlo jQuerye creare una funzione di clic, ma penso che questa funzionalità dovrebbe essere inclusa nel bootstrap? Quindi forse è un problema di JavaScript?

Ecco la mia intestazione con i miei file js / css / bootstrap che ho incluso:

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

Ecco il mio navbarcodice:

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

Lo sto impostando bene?

(Su una nota non correlata, ma possibile correlata? Quando il menu diventa mobile, faccio clic sul pulsante del menu e si comprime. Premendolo di nuovo non viene annullato il compresso. Quindi questo problema ,. con l'altro, entrambi indicano una configurazione JavaScript errata Forse?)


3
Da quando lavoro con bootstrap, penso che Boostrap non lo gestisca, devi impostare tu stesso la classe attiva ... Se sbaglio, imparerò molto con esso ...
BENARD Patrick

1
Bene, @TheLittlePig è corretto, devi aggiungere la activeclasse tu stesso quando la tua applicazione genera l'HTML.
DavidG

Risposte:


144

Hai incluso il file Bootstrap js minimizzato e i plug-in di compressione / transizione mentre i documenti affermano che:

Sia bootstrap.js che bootstrap.min.js contengono tutti i plugin in un unico file.
Includine solo uno.

e

Per effetti di transizione semplici, includi una volta transizione.js insieme agli altri file JS. Se stai usando bootstrap.js compilato (o minimizzato), non è necessario includerlo: è già lì.

Quindi questo potrebbe essere il tuo problema per minimizzare il problema.

Per la classe attiva, devi gestirla da solo, ma è solo una o due righe.

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
Funziona se ti sposti da una pagina all'altra in href(non hash ma invii un'altra richiesta)?
Blaszard

1
@Blaszard in app / siti non a pagina singola dovresti avere una activeclasse navsull'elemento per impostazione predefinita.
Pete TNT

Non funziona per me. La voce dell'elenco non viene mai visualizzata come attiva !? Cosa non sto facendo quello che state facendo voi ragazzi?
user465342

4
non funziona per me, viene aggiunto ma nel secondo successivo andrà alla classe attiva iniziale quindi non rimane sulla pagina per favore chiunque aiuti su questo
sourav78611

9
@Pete TNT - Non è ancora chiaro ed è molto frustrante quando le persone danno il 90% di una solitaria e presumono che tutti sappiano come applicare il restante 10%. Soprattutto negli scenari in cui è difficile ottenere la sintassi corretta.
Dave

96

Ecco la mia soluzione per cambiare le pagine attive

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

2
Dove dovremmo metterlo? Scusate; nuovo per JS: #
mrateb

2
Funziona bene in Bootstrap 4. @ Thomas8: dovrebbe essere compreso tra i tag <script>e </script> tags at the bottom of the html file before the </body> `(assumendo che tu abbia tutto in un file html).
curioso

aggiunto lo stesso in site.js senza alcun tag <script> e ha funzionato $ (document) .ready (function () {$ ('li.active'). removeClass ('active'); $ ('a [href = "'+ location.pathname +'"] '). più vicino (' li '). addClass (' active ');});
Oracular Man

Per me questa è stata l'unica soluzione che ha funzionato su bootstrap 3.3.7 molte grazie.
MitchellK

Questa soluzione alla fine ha funzionato per me. Ho aggiunto la funzione: console.log (location.pathname) e mi sono reso conto, nella <a href='foo/bar>, di aver perso l'ultima "/", se cambio in <a href = 'foo / bar / '>, questa funzione funziona per rendere attivo il "li" destro sulla barra di navigazione.
Emily

16

Questo ha funzionato perfettamente per me, perché "window.location.pathname" contiene anche dati prima del vero nome della pagina, ad esempio directory / page.php. Quindi il collegamento effettivo della barra di navigazione sarà impostato su attivo solo se l'URL contiene questo collegamento.

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

5
tutte le altre soluzioni non funzionano tranne la tua, le ho provate una per una
Lynob

14

Con la versione 3.3.4 di bootstrap, su lunghe pagine html puoi fare riferimento alle sezioni del pg. per classe o id per gestire il collegamento attivo della barra di navigazione con spy-scroll con l'elemento body:

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

Il data-target sarà 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>

Questo dovrebbe attivare i collegamenti facendo clic senza alcuna funzione javascript necessaria e inoltre attiverà automaticamente ogni collegamento mentre si scorrono le sezioni collegate corrispondenti della pagina, cosa che un js onclick () non lo farà.


1
Grazie. Dovrebbe essere: data-target = "# spy-scroll-id" e non data-target = "spy-scroll-id"
Vdex

10

Tutto quello che devi fare è semplicemente aggiungere data-toggle = "tab" al tuo link all'interno della barra di navigazione bootstrap in questo modo:

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

questo è davvero utile, ma non funziona quando hai un navbar-nav (normale) e anche un secondo elenco navbar-right. Finisci con due attivi che non vengono mai cancellati
Karl P

5
quando aggiungo "data-toggle", la pagina non può andare al "#place" specificato in href.
scorpiozj

In realtà un aggiornamento. Come menzionato da @scorpiozj. Quando viene aggiunto, il collegamento stesso non funziona
mrateb

9

Se non usi i link di ancoraggio, puoi usare qualcosa del genere:

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

6

Con Bootstrap 4 puoi usare questo:

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

Grazie, non ho idea del perché gli altri (Bootstrap 3) non funzionassero
information_interchange

4

Questa soluzione elegante ha funzionato per me. Eventuali nuove idee / suggerimenti sono i benvenuti.

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

È possibile utilizzare il metodo "siblings ()" di jQuery per mantenere attivo solo l'elemento a cui si accede e i suoi fratelli inattivi.


2

Oggi ho lottato con questo, data-togle ha funzionato solo se sono su un'applicazione a pagina singola.

Non sto usando ajax per caricare il contenuto che sto effettivamente facendo richieste di post per altre pagine, quindi anche il primo script js era inutile. Lo risolvo con queste righe:

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

1

Spero che questo aiuti a risolvere questo 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

Ho avuto qualche problema con questo, utilizzando un elenco di elementi generati dinamicamente - WordPress Stack.

Aggiunto questo e ha funzionato:

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

Lo farò al volo.


1

Io uso questo. È breve, elegante e di facile comprensione.

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


0

Per annullare la compressione del menu mobile bootstrap dopo aver fatto clic su un elemento, puoi utilizzarlo

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

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

0

Sto usando il tema bootstrap nudo, ecco il codice navbar di esempio. Notare il nome della classe dell'elemento -> .nav - poiché viene indicato nello 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

nella pagina di visualizzazione (o parziale) aggiungi questo: javascript, deve essere eseguito ogni volta che la pagina viene caricata.

snippet di visualizzazione haml ->

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

Nel debugger javascript assicurati che il valore dell'attributo 'href' corrisponda a window.location.pathname. Questo è leggermente diverso dalla soluzione di @Zitrax che mi ha aiutato a risolvere il mio problema.


0

Per AngularJS, puoi usare ng-classcon una funzione come questa:

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

Se stai usando $ location, non ci sarà hash. Quindi puoi estrarre la stringa richiesta dall'URL usando $ location

Quanto segue non funzionerà in tutti i casi ->

L'utilizzo di una variabile di ambito come la seguente funzionerà solo quando si fa clic, ma se la transizione viene eseguita utilizzando $state.transitionToo window.location o aggiornando manualmente l'URL, il valore Tab non verrà aggiornato

<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

Aggiungi questo JavaScript al tuo file js principale.

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

3
Aggiungi la descrizione della soluzione.
sg7

0

Ho dovuto fare un passo avanti perché i nomi dei miei file non erano gli stessi dei titoli della mia barra di navigazione. cioè il mio primo collegamento alla barra di navigazione era HOME ma il nome del file è index ..

Quindi prendi il nome del percorso e abbinalo.

Ovviamente questo è un esempio grezzo e potrebbe essere più efficiente, ma è un'esigenza altamente personalizzata.

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

Soluzione Bootstrap 4 che ha funzionato per me:

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

Funzionerà solo se href contiene location.pathname !

Se stai testando il tuo sito sul tuo PC (usando wamp, xampp, lamp, ecc ...) e il tuo sito si trova in una sottocartella, il tuo percorso è in realtà "/somefolder/something.php", quindi non farlo confuso.

Suggerirei se non sei sicuro di utilizzare il seguente codice in modo da poter assicurarti qual è il percorso corretto .

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

0

la prossima risposta è per chi ha un menù multi-livello:

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

Esempio di come funziona


0

Come qualcuno che non conosce javascript, ecco un metodo PHP che funziona per me ed è facile da capire. La mia intera barra di navigazione è in una funzione PHP che si trova in un file di componenti comuni che includo dalle mie pagine. Quindi per esempio nella mia pagina 'index.php' ho ... `

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

Quindi nel 'my_common_includes.php' ho ...

<?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 richiede di scegliere come target l' lielemento per le classi attive. Per farlo devi trovare il genitore del file a. La "hitbox" di aè grande quanto la lima a causa del ribollire dell'evento in JS ti restituirà l' aevento. Quindi devi aggiungerlo manualmente al suo genitore.

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

0

Ho provato le prime 5 soluzioni e diverse varianti di esse, ma non hanno funzionato per me.

Finalmente ho funzionato con queste due funzioni.

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

quando si usa header.php per ogni pagina per il codice navbar, il jquery non funziona, l'attivo viene applicato e poi rimosso, una soluzione semplice, è la seguente

in ogni variabile del set <?php $pageName = "index"; ?>di pagine nella pagina Indice e analogamente <?php $pageName = "contact"; ?>nella pagina Contattaci

quindi chiama header.php (cioè il codice di navigazione è in header.php) <?php include('header.php'); >

nel header.php assicurati che ogni link di navigazione sia il seguente

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

spero che questo aiuti perché ho impiegato giorni per far funzionare il jquery ma non è riuscito,

se qualcuno spiegasse gentilmente qual è esattamente il problema quando è incluso header.php e poi la pagina viene caricata ... perché jquery non riesce ad aggiungere la classe attiva al nav-link .. ??


0

Sto cercando una soluzione che posso utilizzare sulle barre di navigazione bootstrap 4 e altri gruppi di collegamenti.

Per un motivo o per l'altro la maggior parte delle soluzioni non ha funzionato, specialmente quelle che cercano di aggiungere "attivo" ai link onclick perché ovviamente una volta cliccato il link se ti porta a un'altra pagina, allora l '"attivo" che hai aggiunto non sarà lì perché il DOM è cambiato. Molte delle altre soluzioni non funzionavano perché spesso non corrispondevano al collegamento o ne abbinavano più di uno.

Questa elegante soluzione va bene per i collegamenti che sono diversi ad esempio: about.php, index.php, ecc ...

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

Tuttavia, quando si trattava degli stessi collegamenti con stringhe di query diverse come index.php? Tag = a, index.php? Tag = b, index.php? Tag = c li avrebbe impostati tutti su attivi a seconda di quale fosse stato cliccato come è corrispondendo al nome del percorso non anche alla query.

Quindi ho provato questo codice che corrisponde al nome del percorso e alla stringa di query e ha funzionato su tutti i collegamenti con stringhe di query, ma quando si fa clic su un collegamento come index.php, vengono attivati ​​anche i collegamenti di stringhe di query simili. Questo perché la mia funzione restituisce una stringa vuota se non è presente una stringa di query nel collegamento, ancora una volta corrispondente al percorso.

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

Quindi alla fine ho abbandonato questo percorso e l'ho mantenuto semplice e l'ho scritto.

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

Funziona su tutti i collegamenti con o senza stringhe di query perché element.href e location.href restituiscono entrambi il percorso completo. Per altri menu ecc. Puoi semplicemente cambiare il selettore della classe genitore (barra di navigazione) con un altro, ad esempio:

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

Un'ultima cosa che sembra importante e che è la libreria js e css che stai usando, ma forse è un altro post. Spero che questo aiuti e contribuisca.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.