Активное состояние панели навигации Bootstrap не работает


91

У меня бутстрап v3.

Я использую class="active"на своем navbarи он не переключается при нажатии пунктов меню. Я знаю, как это сделать, jQueryи создать функцию щелчка, но я думаю, что эту функцию нужно включить в загрузку? Так, может быть, это проблема JavaScript?

Вот мой заголовок с моими js / css / bootstrap файлами, которые я добавил:

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

Вот мой 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>

Я правильно это настраиваю?

(Несвязанная заметка, но, возможно, связанная? Когда меню становится мобильным, я нажимаю кнопку меню, и оно сворачивается. Повторное нажатие не отменяет его сворачивание. Таким образом, эта проблема, вместе с другой, означает неправильную настройку JavaScript. возможно?)


3
Поскольку я работаю с бутстрапом, я думаю, что Boostrap не справляется с этим, вы должны сами установить активный класс ... Если я ошибаюсь, я многому научусь с ним ...
БЕНАРД Патрик

1
Что ж, @TheLittlePig правильный, вам нужно добавить activeкласс самостоятельно, когда ваше приложение генерирует HTML.
DavidG 01

Ответы:


143

Вы включили миниатюрный файл Bootstrap js и плагины свертывания / перехода, а в документации указано, что:

И bootstrap.js, и bootstrap.min.js содержат все плагины в одном файле.
Включите только один.

а также

Для простых эффектов перехода включите transition.js один раз вместе с другими файлами JS. Если вы используете скомпилированный (или миниатюрный) bootstrap.js, нет необходимости включать его - он уже есть.

Так что это вполне может быть вашей проблемой для проблемы минимизации.

Что касается активного класса, вы должны управлять им самостоятельно, но это всего лишь пара строк.

Бутстрап 3:

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

Загрузочный: http://www.bootply.com/IsRfOyf0f9

Бутстрап 4:

$(".nav .nav-link").on("click", function(){
   $(".nav").find(".active").removeClass("active");
   $(this).addClass("active");
});

2
Работает ли это, если вы переходите со страницы на другую в href(не хеш, а отправляете другой запрос)?
Blaszard

1
@Blaszard в не одностраничных приложениях / сайтах у вас должен быть activeкласс по этому navэлементу по умолчанию.
Pete TNT

У меня не работает. Элемент списка никогда не отображается как активный !? Что я не делаю, что делаете вы, ребята?
user465342

4
он не работает для меня, он добавляется, но в следующую секунду он переходит в начальный активный класс, поэтому он не остается на странице, пожалуйста, помогите кому-нибудь в этом
sourav78611

9
@Pete TNT - Это все еще неясно и очень неприятно, когда люди отдают 90% раствора и предполагают, что все знают, как применить оставшиеся 10%. Особенно в сценариях, когда сложно получить правильный синтаксис.
Дэйв

97

Вот мое решение для переключения активных страниц

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

2
Куда это положить? Сожалею; новое в JS: #
mrateb

2
Это отлично работает в Bootstrap 4. @ Thomas8: это должно быть между тегом <script>и </script> tags at the bottom of the html file before the </body> `(при условии, что у вас все в одном html-файле).
alwaysCurious

добавил то же самое в site.js без тега <script>, и он работал $ (document) .ready (function () {$ ('li.active'). removeClass ('active'); $ ('a [href = "'+ location.pathname +'"] '). closest (' li '). addClass (' active ');});
Oracular Man

Для меня это было единственное решение, которое сработало с начальной загрузкой 3.3.7, большое спасибо.
MitchellK

Это решение в конечном итоге сработало для меня. Я добавил функцию: console.log (location.pathname) и понял, что в <a href='foo/bar> я пропустил последний «/», если я перейду на <a href = 'foo / bar / '>, то эта функция работает для того, чтобы активировать правый "li" на панели навигации.
Эмили

16

Это отлично сработало для меня, потому что "window.location.pathname" также содержит данные перед настоящим именем страницы, например, directory / page.php. Таким образом, фактическая ссылка на навигационной панели будет активна только в том случае, если URL-адрес содержит эту ссылку.

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

5
все другие решения не работают, кроме вашего, я пробовал их одно за другим
Lynob

14

В версии 3.3.4 начальной загрузки на длинных html-страницах вы можете ссылаться на разделы файла pg. по классу или идентификатору для управления активной ссылкой на панели навигации с помощью шпионской прокрутки с элементом body:

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

Целью данных будет div с 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>

Это должно активировать ссылки по щелчку без каких-либо необходимых функций javascript, а также автоматически активирует каждую ссылку при прокрутке соответствующих связанных разделов страницы, чего не будет с js onclick ().


1
Спасибо. Это должно быть: data-target = "# spy-scroll-id", а не data-target = "spy-scroll-id"
Vdex

10

Все, что вам нужно сделать, это просто добавить data-toggle = "tab" к вашей ссылке внутри начальной панели навигации, например:

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

это действительно полезно, но не работает, когда у вас есть navbar-nav (обычный), а также второй список navbar-right. У вас останутся два активных, которые никогда не сбрасываются
Karl P

5
когда я добавляю «data-toggle», страница не может перейти в «#place», указанное в href.
scorpiozj

Собственно обновление. Как упоминалось в @scorpiozj. Когда это добавлено, сама ссылка не работает
mrateb

9

Если вы не используете якорные ссылки, вы можете использовать что-то вроде этого:

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

6

С Bootstrap 4 вы можете использовать это:

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

Спасибо, понятия не имею, почему другие (Bootstrap 3) не работали
information_interchange

4

Это элегантное решение помогло мне. Любые новые идеи / предложения приветствуются.

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

Вы можете использовать метод jQuery «siblings ()», чтобы поддерживать активным только элемент, к которому осуществляется доступ, а его «братья и сестры» неактивны.


2

Сегодня я боролся с этим, переключение данных работает только в том случае, если я использую одностраничное приложение.

Я не использую ajax для загрузки контента, я фактически отправляю запрос на публикацию для других страниц, поэтому первый скрипт js тоже был бесполезен. Я решаю это следующими строками:

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

1

Надеюсь, это поможет решить эту проблему.

      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

У меня были некоторые проблемы с использованием динамически генерируемых элементов списка - WordPress Stack.

Добавил это, и это сработало:

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

Сделаю это на лету.


1

Я использую это. Он короткий, элегантный и легкий для понимания.

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


0

Для разблокировки мобильного меню начальной загрузки после нажатия на элемент вы можете использовать это

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

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

0

Я использую голую тему начальной загрузки, вот пример кода навигационной панели. Обратите внимание на имя класса элемента -> .nav - как это указано в 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

на странице просмотра (или частично) добавьте это: javascript, это должно выполняться каждый раз при загрузке страницы.

фрагмент просмотра haml ->

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

В отладчике javascript убедитесь, что значение атрибута 'href' совпадает с window.location.pathname. Это немного отличается от решения @Zitrax, которое помогло мне исправить мою проблему.


0

For AngularJSвы можете использовать ng-classс такой функцией:

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>

И контроллер

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

Если вы используете $ location, то хеша не будет. Таким образом, вы можете извлечь необходимую строку из URL-адреса, используя $ location

Следующее не будет работать во всех случаях ->

Использование переменной области видимости, такой как следующая, будет работать только при нажатии, но если переход выполняется с помощью $state.transitionToили window.location или вручную обновляется URL-адрес, значение Tab не будет обновлено

<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

Добавьте этот JavaScript в свой основной файл js.

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

3
Пожалуйста, добавьте описание решения.
sg7

0

Мне пришлось сделать шаг вперед, потому что имена моих файлов не совпадали с названиями моей панели навигации. то есть моя первая ссылка на навигационную панель была HOME, но имя файла - index.

Так что просто возьмите путь и сопоставьте его.

Очевидно, что это грубый пример, и он мог бы быть более эффективным, но это очень нестандартная потребность.

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, которое сработало для меня:

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

Это будет работать, только если href содержит location.pathname !

Если вы тестируете свой сайт на собственном компьютере (используя wamp, xampp, lamp и т. Д.), И ваш сайт находится в какой-то подпапке, то ваш путь на самом деле «/somefolder/something.php», поэтому не получайте смущенный.

Я бы посоветовал, если вы не уверены, что используете следующий код, чтобы вы могли убедиться, что является правильным location.pathname :

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

0

следующий ответ для тех, у кого многоуровневое меню:

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

Пример как это работает


0

Как человек, не знакомый с javascript, вот метод PHP, который подходит мне и прост для понимания. Вся моя панель навигации находится в функции PHP, которая находится в файле общих компонентов, которые я включаю со своих страниц. Так, например, на моей странице index.php у меня есть ...

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

Затем в 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

Bootstrap 4 требует, чтобы вы нацелили liэлемент на активные классы. Для этого вам нужно найти родительский объект a. «Hitbox» такой aже большой, как и, liно из-за всплытия события в JS он вернет вам aсобытие. Поэтому вам нужно вручную добавить его к родительскому.

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

0

Я пробовал первые 5 решений и разные их варианты, но они у меня не сработали.

Наконец-то у меня получилось работать с этими двумя функциями.

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

при использовании header.php для каждой страницы для кода навигационной панели jquery не работает, активный элемент применяется, а затем удаляется, простое решение выглядит следующим образом

на каждой странице установить переменную <?php $pageName = "index"; ?>на странице индекса и аналогично <?php $pageName = "contact"; ?> на странице "Свяжитесь с нами"

затем вызовите header.php (т.е. код навигации находится в header.php) <?php include('header.php'); >

в header.php убедитесь, что каждая навигационная ссылка выглядит следующим образом

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

надеюсь, это поможет, потому что я потратил несколько дней, чтобы заставить jquery работать, но не удалось,

если кто-то любезно объяснит, в чем именно заключается проблема, когда включается header.php, а затем загружается страница ... почему jquery не может добавить активный класс к навигационной ссылке .. ??


0

Я искал решение, которое я могу использовать для начальной загрузки 4 навигационных панелей и других групп ссылок.

По той или иной причине большинство решений не работали, особенно те, которые пытаются добавить «активные» к ссылкам при нажатии, потому что, конечно, после нажатия ссылки, если она ведет вас на другую страницу, добавленные вами «активные» не будут там, потому что DOM изменился. Многие другие решения не работали, потому что они часто не соответствовали ссылке или совпадали более чем с одной.

Это элегантное решение подходит для разных ссылок, например: about.php, index.php и т. Д.

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

Однако, когда дело доходит до тех же ссылок с разными строками запроса, такими как index.php? Tag = a, index.php? Tag = b, index.php? Tag = c, все они становятся активными независимо от того, по какой из них щелкнули соответствие имени пути, а не запроса.

Итак, я попробовал этот код, который соответствовал имени пути и строке запроса, и он работал со всеми ссылками со строками запроса, но когда была нажата ссылка, такая как index.php, она также установила аналогичные ссылки строки запроса активными. Это связано с тем, что моя функция возвращает пустую строку, если в ссылке нет строки запроса, снова просто совпадая с именем пути.

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

Так что в конце концов я отказался от этого маршрута и, оставив его простым, написал это.

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

Он работает со всеми ссылками со строками запроса или без них, потому что element.href и location.href возвращают полный путь. Для других меню и т. Д. Вы можете просто изменить селектор родительского класса (панель навигации) на другой, например:

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

И последнее, что также кажется важным, и это библиотека js и css, которую вы используете, но, возможно, это еще один пост. Я надеюсь, что это поможет и внесет свой вклад.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.