Twitter Bootstrap-Tabs-URL не меняется


Я использую Twitter Bootstrap и его "вкладки".

у меня есть следующий код:

<ul class="nav nav-tabs">
    <li class="active"><a data-toggle="tab" href="#add">add</a></li>
    <li><a data-toggle="tab" href="#edit" >edit</a></li>
    <li><a data-toggle="tab" href="#delete" >delete</a></li>
</ul>

вкладки работают правильно, но в URL не добавляется #add, #edit, #delete.

когда я удалить data-toggle URL изменяется, но вкладки не работают.

какие-либо решения для этого?

14 91

14 ответов:

попробуйте этот код. Он добавляет вкладку href в url + открывает вкладку на основе хэша при загрузке страницы:

$(function(){
  var hash = window.location.hash;
  hash && $('ul.nav a[href="' + hash + '"]').tab('show');

  $('.nav-tabs a').click(function (e) {
    $(this).tab('show');
    var scrollmem = $('body').scrollTop() || $('html').scrollTop();
    window.location.hash = this.hash;
    $('html,body').scrollTop(scrollmem);
  });
});

есть три компонента, необходимые для полного решения:

  1. показать правильную вкладку при загрузке страницы, если есть хэш в URL.
  2. изменение хэша в URL-адресе при изменении вкладки.
  3. измените вкладку, когда хэш изменяется в URL (кнопки Назад / Вперед), и убедитесь, что первая вкладка циклически правильно.

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

поскольку там довольно много задействовано, я думаю, что это самый аккуратный как небольшой плагин jQuery: https://github.com/aidanlister/jquery-stickytabs

вы можете вызвать плагин вот так:

$('.nav-tabs').stickyTabs();

Я сделал сообщение в блоге для этого, http://aidanlister.com/2014/03/persisting-the-tab-state-in-bootstrap/

используя data-toggle="tab"просит плагин для обработки вкладок, который при этом вызывает preventDefault на мероприятии (код на github).

вы можете использовать свою собственную вкладку активации, и пусть событие пройти:

$('.nav-tabs a').click(function (e) {
    // No e.preventDefault() here
    $(this).tab('show');
});

и вы должны удалить атрибут data-toggle="tab"

Регистрация док если у вас есть сомнения.

Как ваши якорные элементы уже изменить хэш url, слушая onhashchange событие-это еще один хороший вариант. Как уже упоминалось @flori, этот метод хорошо работает с кнопкой возврата браузера.

var tabs$ = $(".nav-tabs a");

$( window ).on("hashchange", function() {
    var hash = window.location.hash, // get current hash
        menu_item$ = tabs$.filter('[href="' + hash + '"]'); // get the menu element

    menu_item$.tab("show"); // call bootstrap to show the tab
}).trigger("hashchange");

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

мое решение вашей проблемы:

добавить новый data-value атрибут для каждого a ссылка, например:

<ul class="nav nav-tabs">
    <li class="active">
        <a data-toggle="tab" href="#tab-add" data-value="#add">add</a>
    </li>
    <li>
        <a data-toggle="tab" href="#tab-edit" data-value="#edit">edit</a>
    </li>
    <li>
        <a data-toggle="tab" href="#tab-delete" data-value="#delete">delete</a>
    </li>
</ul>

во-вторых, измените идентификаторы вкладок, например, от add до tab-add, также обновите hrefs, чтобы включить tab- префикс:

<div class="tab-content">
    <div class="tab-pane" id="tab-add">Add panel</div>
    <div class="tab-pane" id="tab-edit">Edit panel</div>
    <div class="tab-pane" id="tab-delete">Panel panel</div>
</div>

и, наконец, код js:

<script type="text/javascript">
    $(function () {
        var navTabs = $('.nav-tabs a');
        var hash = window.location.hash;
        hash && navTabs.filter('[data-value="' + hash + '"]').tab('show');

        navTabs.on('shown', function (e) {
            var newhash = $(e.target).attr('data-value');
            window.location.hash = newhash;
        });
    })
</script>

здесь jsFiddle - но это не работает из-за iframe, используемого jsFiddle, но вы можете прочитать источник моего решения.

существует также простой способ реагировать на изменения хэша (например, кнопка Назад). Просто добавьте прослушиватель событий hashchange в решение tomaszbak:

$(function(){
  // Change tab on load
  var hash = window.location.hash;
  hash && $('ul.nav a[href="' + hash + '"]').tab('show');

  $('.nav-tabs a').click(function (e) {
    $(this).tab('show');
    var scrollmem = $('body').scrollTop();
    window.location.hash = this.hash;
    $('html,body').scrollTop(scrollmem);
  });

  // Change tab on hashchange
  window.addEventListener('hashchange', function() {
    var changedHash = window.location.hash;
    changedHash && $('ul.nav a[href="' + changedHash + '"]').tab('show');
  }, false);
});

та же проблема с CakePHP с вкладками Bootstrap 3, плюс когда я отправляю с внешним URL и привязкой, он переходит в раздел, теряющий мое меню, после просмотра многих решений, сделанных это...

Спасибо:http://ck.kennt-wayne.de/2012/dec/twitter-bootstrap-how-to-fix-tabs

$(document).ready(function()
 {  
//Redirecciona al tab, usando un prefijo al cargar por primera vez, al usar redirect en cake #_Pagos    
//Redirecciona al tab, usando #Pagos
/* Automagically jump on good tab based on anchor; for page reloads or links */
 if(location.hash) 
  {
     $('a[href=' + location.hash + ']').tab('show');         
  }


//Para evitar el bajar al nivel del tab, (al mostrarse el tab subimos)
$('a[data-toggle="tab"]').on('shown.bs.tab', function(e) 
{
    location.hash = $(e.target).attr('href').substr(1);
    scrollTo(0,0);      
});



//Actualiza el URL con el anchor o ancla del tab al darle clic
 /* Update hash based on tab, basically restores browser default behavior to
 fix bootstrap tabs */
$(document.body).on("click", "a[data-toggle]", function(event) 
  {
    location.hash = this.getAttribute("href");
  });


//Redirecciona al tab, al usar los botones de regresar y avanzar del navegador.
/* on history back activate the tab of the location hash if exists or the default tab if no hash exists */   
$(window).on('popstate', function() 
{
  //Si se accesa al menu, se regresa al tab del perfil (activo default), fixed conflict with menu
  //var anchor = location.hash || $("a[data-toggle=tab]").first().attr("href");
  var anchor = location.hash;
  $('a[href=' + anchor + ']').tab('show');

});   

});//Fin OnReady

самый простой, предполагая, что вы используете документально data-toggle="tab" синтаксис, описанный здесь:

$(document).on('shown.bs.tab', function(event) {
  window.location.hash = $(event.target).attr('href');
});

для тех, кто использует Ruby on Rails или любой другой скрипт на стороне сервера, вы захотите использовать на пути. Это происходит потому, что после того, как страница загрузится, он не имеет URL-адрес хэш доступен. Вы захотите указать правильную вкладку через свою ссылку или форму отправки.

<%= form_for @foo, url: foo_path(@foo, anchor: dom_id(foo)) do |f| %>
# Or
<%= link_to 'Foo', foo_path(@foo, anchor: dom_id(foo)) %>

если вы используете префикс для предотвращения перехода окна к идентификатору:

<%= form_for @foo, url: foo_path(@foo, anchor: "bar_#{dom_id(foo)}") do |f| %>

тогда вы CoffeeScript:

  hash = document.location.hash
  prefix = 'bar_'
  $('.nav-tabs a[href=' + hash.replace(prefix, '') + ']').tab 'show' if hash
  $('.nav-tabs a').on 'shown.bs.tab', (e) ->
    window.location.hash = e.target.hash.replace '#', '#' + prefix

Или JavaScript:

var hash, prefix;

hash = document.location.hash;
prefix = 'bar_';

if (hash) {
  $('.nav-tabs a[href=' + hash.replace(prefix, '') + ']').tab('show');
}

$('.nav-tabs a').on('shown.bs.tab', function(e) {
  window.location.hash = e.target.hash.replace('#', '#' + prefix);
});

этот должен работать в Bootstrap 3.

спасибо @tomaszbak для оригинального решения, однако, поскольку мои изменения были отклонены, и я не могу прокомментировать его сообщение, я оставлю свою немного улучшенную и более читаемую версию здесь.

он делает в основном то же самое, но если исправляет проблему совместимости кросс-браузера, которую я имел с ним.

$(document).ready(function(){
   // go to hash on window load
   var hash = window.location.hash;
   if (hash) {
       $('ul.nav a[href="' + hash + '"]').tab('show');
   }
   // change hash on click
   $('.nav-tabs a').click(function (e) {
       $(this).tab('show');
       if($('html').scrollTop()){
           var scrollmem = $('html').scrollTop(); // get scrollbar position (firefox)
       }else{
           var scrollmem = $('body').scrollTop(); // get scrollbar position (chrome)
       }
       window.location.hash = this.hash;
       $('html,body').scrollTop(scrollmem); // set scrollbar position
   });
});

вот вариант с использованием history.pushState, Так что вы можете использовать историю браузера, чтобы вернуться к предыдущей вкладке

  $(document).ready(function() {
  // add a hash to the URL when the user clicks on a tab
  $('a[data-toggle="tab"]').on('click', function(e) {
    history.pushState(null, null, $(this).attr('href'));
  });
  // navigate to a tab when the history changes
  window.addEventListener("popstate", function(e) {
    var activeTab = $('[href=' + location.hash + ']');
    if (activeTab.length) {
      activeTab.tab('show');
    } else {
      $('.nav-tabs a:first').tab('show');
    }
  });
});

Я использую Bootstrap 3.3.* и ни одно из вышеперечисленных решений не помогло мне, даже помеченное как ответ один. Я просто добавил ниже скрипт и работал.

$(function(){
    var hash = document.location.hash;
    if (hash) {
       $('.navbar-nav a[href="' + hash + '"]').tab('show');
    }
    $('a[data-toggle="tab"]').on('click', function (e) {
       history.pushState(null, null, $(this).attr('href'));
    });
});

надеюсь, что это поможет вам.

ни один из вышеперечисленных не работал для меня, так что вот как я получил свою работу:

  1. добавить class="tab-link" для всех ссылок, нуждающихся в этой функциональности
  2. добавьте следующий код в ваш javascript:
    window.addEventListener
    (
        'popstate',
        function( event )
        {
            tab_change();
        }
    );

    function tab_change()
    {
        var hash = window.location.hash;
        hash && $( 'ul.nav a[href="' + hash + '"]' ).tab( 'show' );

        $( '.tab-link' ).click
        (
            function( e )
            {
                $( this ).tab( 'show' );

                var scrollmem = $( 'body' ).scrollTop() || $( 'html' ).scrollTop();
                window.location.hash = this.hash;
                $( 'html,body' ).scrollTop( scrollmem );

                $( 'ul.nav-tabs a[href="' + window.location.hash + '"]' ).tab( 'show' );
            }
        );
    }

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

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> 

<script type="text/javascript">
$('.nav-tabs a').click(function (e) {
    // No e.preventDefault() here.
    $(this).tab('show');
});
</script>

<script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.2.1/js/bootstrap.min.js"></script>