Pasek nawigacyjny Bootstrap Active State nie działa


91

Mam bootstrap v3.

Używam class="active"na moim navbari nie przełącza się, gdy naciskam pozycje menu. Wiem, jak to zrobić jQueryi zbudować funkcję kliknięcia, ale myślę, że ta funkcja powinna być zawarta w bootstrapie? Więc może to problem JavaScript?

Oto mój nagłówek z plikami js / css / bootstrap, które dołączyłem:

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

Oto mój navbarkod:

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

Czy to konfiguruję, prawda?

(To niepowiązane notatki, ale możliwe, że powiązane? Kiedy menu staje się mobilne, klikam przycisk menu i się zwija. Ponowne naciśnięcie go jednak nie powoduje jego zwinięcia. Tak więc ten problem, z drugiej strony, oznacza niewłaściwą konfigurację JavaScript być może?)


3
Odkąd pracuję z bootstrapem, myślę, że Boostrap nie daje rady, musisz sam ustawić aktywną klasę ... Jeśli się mylę, wiele się z tego
nauczę

1
Cóż, @TheLittlePig jest poprawne, musisz dodać activeklasę samodzielnie, gdy aplikacja generuje kod HTML.
DavidG,

Odpowiedzi:


143

Dołączono zminimalizowany plik Bootstrap js i wtyczki zwijania / przejścia, podczas gdy dokumentacja stwierdza, że:

Zarówno bootstrap.js, jak i bootstrap.min.js zawierają wszystkie wtyczki w jednym pliku.
Uwzględnij tylko jeden.

i

Aby uzyskać proste efekty przejścia, umieść przejście.js razem z innymi plikami JS. Jeśli używasz skompilowanego (lub zminimalizowanego) pliku bootstrap.js, nie ma potrzeby dołączania tego - już tam jest.

Więc to może być twój problem z problemem minimalizacji.

W przypadku aktywnych zajęć musisz samodzielnie zarządzać, ale to tylko jedna lub dwie linie.

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
Czy to działa, jeśli przejdziesz ze strony na inną w href(nie hash, ale wyślesz kolejne żądanie)?
Blaszard

1
@Blaszard w aplikacjach / witrynach niebędących jedną stroną powinieneś mieć domyślnie activeklasę na navelemencie.
Pete TNT

Nie działa dla mnie. Element listy nigdy nie jest wyświetlany jako aktywny !? Czego ja nie robię, czego wy robicie?
user465342

4
nie działa dla mnie, jest dodawany, ale w następnej sekundzie przechodzi do początkowej aktywnej klasy, więc nie zostaje na stronie, proszę o pomoc w tej sprawie
sourav78611

9
@Pete TNT - Nadal nie jest jasne i jest to bardzo frustrujące, gdy ludzie dają 90% rozwiązania i zakładają, że wszyscy wiedzą, jak zastosować pozostałe 10%. Zwłaszcza w scenariuszach, w których trudno jest uzyskać właściwą składnię.
Dave

97

Oto moje rozwiązanie do przełączania aktywnych stron

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

2
Gdzie powinniśmy to umieścić? Przepraszam; nowy w JS: #
mrateb

2
Działa to dobrze w Bootstrap 4. @ Thomas8: powinno znajdować się pomiędzy tagiem <script>i </script> tags at the bottom of the html file before the </body> `(zakładając, że masz wszystko w jednym pliku html).
alwaysCurious

dodał to samo w site.js bez żadnego tagu <script> i zadziałało $ (document) .ready (function () {$ ('li.active'). removeClass ('active'); $ ('a [href = "'+ nazwa_ścieżki_lokalizacji +'"] '). najbliższy (' li '). addClass (' aktywny ');});
Oracular Man

Dla mnie było to jedyne rozwiązanie, które działało na bootstrap 3.3.7 wielkie dzięki.
MitchellK

To rozwiązanie ostatecznie zadziałało dla mnie. Dodałem w funkcji: console.log (location.pathname) i zdałem sobie sprawę, że w <a href='foo/bar> przegapiłem ostatni "/", jeśli zmienię na <a href = 'foo / bar / '>, to ta funkcja działa w celu uaktywnienia prawego "li" na pasku nawigacyjnym.
Emily,

16

U mnie to zadziałało idealnie, ponieważ „nazwa_okna.lokalizacji” zawiera również dane przed rzeczywistą nazwą strony, np. Katalog / strona.php. Tak więc rzeczywisty link paska nawigacyjnego zostanie ustawiony jako aktywny tylko wtedy, gdy adres URL zawiera ten link.

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

5
wszystkie inne rozwiązania nie działają z wyjątkiem twojego, wypróbowałem je pojedynczo
Lynob

14

W wersji 3.3.4 bootstrapa na długich stronach html możesz odwoływać się do sekcji pg. według klasy lub identyfikatora, aby zarządzać aktywnym linkiem paska nawigacyjnego za pomocą spy-scroll z elementem body:

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

Docelowym elementem danych będzie div z 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>

Powinno to aktywować linki poprzez kliknięcie bez żadnych potrzebnych funkcji javascript, a także automatycznie aktywować każdy link podczas przewijania odpowiednich połączonych sekcji strony, czego nie zrobi js onclick ().


1
Dzięki. Powinien to być: data-target = "# spy-scroll-id", a nie data-target = "spy-scroll-id"
Vdex Kwietnia

10

Wszystko, co musisz zrobić, to po prostu dodać data-toggle = "tab" do swojego linku w pasku nawigacyjnym bootstrap w następujący sposób:

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

jest to bardzo przydatne, ale nie działa, gdy masz navbar-nav (normalną), a także drugą listę navbar-right. Skończysz z dwoma aktywnymi, które nigdy nie są usuwane
Karl P

5
kiedy dodam „data-toggle”, strona nie może przejść do „#place” określonego w href.
scorpiozj

Właściwie aktualizacja. Jak wspomniał @scorpiozj. Kiedy to zostanie dodane, sam link nie działa
mrateb

9

Jeśli nie używasz linków zakotwiczenia, możesz użyć czegoś takiego:

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

6

Dzięki Bootstrap 4 możesz użyć tego:

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

Dzięki, nie mam pojęcia, dlaczego pozostałe (Bootstrap 3) nie działały
information_interchange

4

To eleganckie rozwiązanie załatwiło mi sprawę. Wszelkie nowe pomysły / sugestie są mile widziane.

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

Możesz użyć metody „siblings ()” jQuery, aby zachować aktywny tylko element, do którego uzyskano dostęp, a jego elementy rodzeństwa nieaktywne.


2

Zmagałem się z tym dzisiaj, przełączanie danych działało tylko wtedy, gdy pracuję w aplikacji jednostronicowej.

Nie używam Ajaxa do ładowania treści, tak naprawdę wysyłam żądanie posta dla innych stron, więc pierwszy skrypt js też był bezużyteczny. Rozwiązuję to za pomocą tych linii:

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

1

Mam nadzieję, że pomoże to rozwiązać ten problem.

      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

Miałem trochę bólu z tym, używając dynamicznie generowanych elementów listy - WordPress Stack.

Dodano to i zadziałało:

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

Zrobi to w locie.


1

Używam tego. Jest krótki, elegancki i łatwy do zrozumienia.

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


0

Aby otworzyć menu mobilne bootstrap po kliknięciu elementu, możesz tego użyć

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

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

0

Używam gołego motywu bootstrap, oto przykładowy kod paska nawigacyjnego. Zwróć uwagę na nazwę klasy elementu -> .nav - tak jak jest to określane w skrypcie 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

na stronie widoku (lub częściowo) dodaj to: javascript, to musi być wykonywane za każdym razem, gdy strona się ładuje.

fragment widoku haml ->

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

W debugerze javascript upewnij się, że wartość atrybutu „href” jest zgodna z wartością window.location.pathname. Jest to nieco inne rozwiązanie niż rozwiązanie @Zitrax, które pomogło mi naprawić mój problem.


0

Dla AngularJS, można korzystać ng-classz funkcji takich jak to:

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>

I kontroler

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

Jeśli używasz $ location, nie będzie hasha. Możesz więc wyodrębnić wymagany ciąg z adresu URL za pomocą $ location

Następujące nie będzie działać we wszystkich przypadkach ->

Użycie zmiennej zakresu, takiej jak poniżej, będzie działać tylko po kliknięciu, ale jeśli przejście zostanie wykonane za pomocą $state.transitionTolub window.location lub ręcznie aktualizuje adres URL, wartość Tab nie zostanie zaktualizowana

<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

Dodaj ten JavaScript do swojego głównego pliku js.

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

3
Dodaj opis rozwiązania.
sg7

0

Musiałem zrobić krok do przodu, ponieważ moje nazwy plików nie były takie same jak tytuły moich pasków nawigacyjnych. tj. mój pierwszy link do paska nawigacyjnego był HOME, ale nazwa pliku to index ..

Więc po prostu chwyć ścieżkę i dopasuj ją.

Oczywiście jest to prymitywny przykład i mógłby być bardziej wydajny, ale jest to wysoce niestandardowa potrzeba.

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

Rozwiązanie Bootstrap 4, które działało dla mnie:

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

To zadziała tylko wtedy, gdy href zawiera lokację nazwa_ścieżki !

Jeśli testujesz swoją witrynę na własnym komputerze (używając wamp, xampp, lamp itp.), A Twoja witryna znajduje się w jakimś podfolderze, Twoja ścieżka to w rzeczywistości „/somefolder/something.php”, więc nie otrzymuj zmieszany.

Proponuję, jeśli nie masz pewności, czy użyć następującego kodu, aby upewnić się, jaka jest poprawna lokalizacja. Nazwa ścieżki :

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

0

następna odpowiedź jest dla tych, którzy mają menu wielopoziomowe:

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

Przykład, jak to działa


0

Jako osoba, która nie zna javascript, oto metoda PHP, która działa dla mnie i jest łatwa do zrozumienia. Cały mój pasek nawigacyjny jest w funkcji PHP, która jest w pliku wspólnych komponentów, które dołączam z moich stron. Na przykład na mojej stronie 'index.php' mam ... `

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

Następnie w „my_common_includes.php” mam ...

<?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 wymaga skierowania lielementu na aktywne klasy. Aby to zrobić, musisz znaleźć rodzica a. Pole trafień ajest tak duże, jak the, liale ze względu na bulgot zdarzenia w JS zwróci to azdarzenie. Musisz więc ręcznie dodać go do jego rodzica.

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

0

Próbowałem pierwszych 5 rozwiązań i różnych ich odmian, ale nie działały.

Wreszcie udało mi się pracować z tymi dwoma funkcjami.

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

kiedy używasz header.php dla każdej strony dla kodu navbar, jquery nie działa, aktywny jest stosowany, a następnie usuwany, proste rozwiązanie jest następujące

na każdej stronie ustaw zmienną <?php $pageName = "index"; ?>na stronie indeksu i podobnie <?php $pageName = "contact"; ?>na stronie Kontakt

następnie wywołaj plik header.php (tzn. kod nawigacyjny znajduje się w header.php) <?php include('header.php'); >

w pliku header.php upewnij się, że każdy link nawigacyjny jest następujący

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

Mam nadzieję, że to pomoże, ponieważ spędziłem dni, aby uruchomić jQuery, ale nie udało mi się,

jeśli ktoś uprzejmie wyjaśni, na czym dokładnie polega problem, gdy dołączany jest plik header.php, a następnie strona się ładuje ... dlaczego jquery nie dodaje aktywnej klasy do linku nawigacyjnego .. ??


0

Szukałem rozwiązania, którego mogę użyć na pasku nawigacyjnym bootstrap 4 i innych grupach linków.

Z tego czy innego powodu większość rozwiązań nie zadziałała, zwłaszcza te, które próbują dodać „aktywne” do linków po kliknięciu, ponieważ oczywiście po kliknięciu linku, jeśli prowadzi do innej strony, wówczas dodany „aktywny” nie będzie tam, ponieważ DOM się zmienił. Wiele innych rozwiązań również nie działało, ponieważ często nie pasowały do ​​linku lub pasowały do ​​więcej niż jednego.

To eleganckie rozwiązanie jest dobre w przypadku linków, które są różne, np .: about.php, index.php itp ...

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

Jednak jeśli chodzi o te same linki z różnymi ciągami zapytań, takimi jak index.php? Tag = a, index.php? Tag = b, index.php? Tag = c, ustawiłoby je wszystkie jako aktywne, niezależnie od tego, które kliknięto. pasujące do ścieżki, a nie do zapytania.

Więc wypróbowałem ten kod, który pasował do nazwy ścieżki i ciągu zapytania, i działał na wszystkich linkach z ciągami zapytań, ale kiedy kliknięto łącze takie jak index.php, ustawiłoby to również podobne linki w zapytaniach jako aktywne. Dzieje się tak, ponieważ moja funkcja zwraca pusty ciąg, jeśli w łączu nie ma ciągu zapytania, ponownie po prostu pasuje do nazwy ścieżki.

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

Więc w końcu porzuciłem tę trasę i utrzymałem ją w prostocie i napisałem to.

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

Działa na wszystkich linkach z ciągami zapytań lub bez, ponieważ element.href i location.href zwracają pełną ścieżkę. W przypadku innych menu itp. Możesz po prostu zmienić selektor klasy nadrzędnej (pasek nawigacyjny) na inną, np .:

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

Ostatnią rzeczą, która również wydaje się ważna, jest biblioteka js i css, której używasz, ale być może to kolejny post. Mam nadzieję, że to pomoże i przyczyni się.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.