Вкладки Twitter Bootstrap: перейти к конкретной вкладке на странице «Перезагрузка» или «Гиперссылка»

303

Я разрабатываю веб-страницу, в которой я использую Twitter Bootstrap Framework и их Bootstrap Tabs JS. Он отлично работает, за исключением нескольких незначительных проблем, одним из которых является то, что я не знаю, как перейти непосредственно на конкретную вкладку из внешней ссылки. Например:

<a href="facility.php#home">Home</a>
<a href="facility.php#notes">Notes</a>

следует перейти на вкладку "Главная" и вкладку "Заметки" соответственно при нажатии на ссылки с внешней страницы

Показать ещё 6 комментариев

22 ответа

561
Лучший ответ

Вот мое решение проблемы, возможно, немного поздно. Но это могло бы помочь другим:

// Javascript to enable link to tab
var url = document.location.toString();
if (url.match('#')) {
    $('.nav-tabs a[href="#' + url.split('#')[1] + '"]').tab('show');
} 

// Change hash for page-reload
$('.nav-tabs a').on('shown.bs.tab', function (e) {
    window.location.hash = e.target.hash;
})
  • 75
    Я бы добавил еще 1 дополнительную строку window.scrollTo(0, 0); чтобы Окно всегда прокручивалось вверх
  • 0
    Это прекрасно работает в Chrome, но по какой-то причине ScrollTo не работает в Firefox, есть идеи?
Показать ещё 25 комментариев
195

UPDATE

Для Bootstrap 3 измените .on('shown', ...) на .on('shown.bs.tab', ....)


Это основано на ответе @dubbe и этом принятом ответе SO. В этом случае проблема с window.scrollTo(0,0) работает неправильно. Проблема в том, что при замене хэша url на показанной вкладке браузер будет прокручивать этот хеш с момента его создания на странице. Чтобы обойти это, добавьте префикс, чтобы хэш не ссылался на фактический элемент страницы

// Javascript to enable link to tab
var hash = document.location.hash;
var prefix = "tab_";
if (hash) {
    $('.nav-tabs a[href="'+hash.replace(prefix,"")+'"]').tab('show');
} 

// Change hash for page-reload
$('.nav-tabs a').on('shown', function (e) {
    window.location.hash = e.target.hash.replace("#", "#" + prefix);
});

Пример использования

Если у вас есть панель вкладок с id = "mytab", вам нужно поместить свою ссылку следующим образом:

<a href="yoursite.com/#tab_mytab">Go to Specific Tab </a>
  • 9
    Для начальной загрузки 3 я переключил («показано» ...) на «включен» («показано.bs.tab» ...), и это сработало для меня.
  • 0
    Будет ли простой способ ссылки на закладки, расположенные под определенной вкладкой? У меня есть пять вкладок на моей странице, и под ними у меня есть несколько закладок. То, что я хотел бы, чтобы сделать эти закладки связываемыми снаружи вкладки.
Показать ещё 5 комментариев
47

вы можете вызвать событие click на соответствующей вкладке:

$(document).ready(function(){

  if(window.location.hash != "") {
      $('a[href="' + window.location.hash + '"]').click()
  }

});
  • 0
    Спасибо за чаевые! Это прекрасно работало с одной маленькой проблемой. Обновление страницы не приведет к ее правильной вкладке. Нажав Ctrl + F5 будет. Я изменил код следующим образом: `$ (document) .ready (function () {function getUrlVars () {var vars = {}; var parts = window.location.href.replace (/ [? &] + ([ ^ = &] +) = ([^ &] *) / gi, функция (m, ключ, значение) {vars [ключ] = значение;}); возврат vars;} var action = getUrlVars () ["action" ]; if (action! = "") {$ ('a [href = "#' + action + '"]'). click ()};}); `
  • 0
    Это не сработало для меня на Bootstrap 1.4 ... :(
Показать ещё 1 комментарий
39

Это улучшенная реализация решения dubbe, которое предотвращает прокрутку.

// Javascript to enable link to tab
var url = document.location.toString();
if (url.match('#')) {
    $('.nav-tabs a[href="#'+url.split('#')[1]+'"]').tab('show') ;
} 

// With HTML5 history API, we can easily prevent scrolling!
$('.nav-tabs a').on('shown.bs.tab', function (e) {
    if(history.pushState) {
        history.pushState(null, null, e.target.hash); 
    } else {
        window.location.hash = e.target.hash; //Polyfill for old browsers
    }
})
18

Хотя предоставленное решение для JavaScript может работать, я пошел несколько иначе, не требуя дополнительного JavaScript, но для этого требуется логика. Вы создаете ссылку со стандартным параметром URL, например:

<a href = "http://link.to.yourpage?activeTab=home">My Link</a>

Затем вы просто определяете значение activeTab для записи 'class= "active" ' в соответствующем <li>

Псевдокод (соответствующим образом реализовать на своем языке). Примечание. Я установил вкладку "home" как активную по умолчанию, если в этом примере не указан параметр.

$activetabhome = (params.activeTab is null or params.activeTab == 'home') ? 'class="active"' : '';
$activetabprofile = (params.activeTab == 'profile') ? 'class="active"' : '';

<li $activetabhome><a href="#home">Home</a></li>
<li $activetabprofile><a href="#profile">Profile</a></li>
  • 0
    Я предпочитаю ваше решение решению JS по одной простой причине: JS location.hash будет переходить к идентификатору, в результате чего позиция курсора будет подниматься и опускаться.
  • 0
    Я предпочитаю это решение. Фактически, я создал новые маршруты для вкладок и заново сгенерировал вид, установив соответствующий класс соответствующим образом. Это позволяет избежать головной боли при изменении размера страницы, URL-хэша и прокрутки страницы.
10

Для Bootstrap 3:

$('.nav-tabs a[href="#' + tabID + '"]').tab('show');

https://jsfiddle.net/DTcHh/6638/

8

Я не большой поклонник if... else; поэтому я взял более простой подход.

$(document).ready(function(event) {
    $('ul.nav.nav-tabs a:first').tab('show'); // Select first tab
    $('ul.nav.nav-tabs a[href="'+ window.location.hash+ '"]').tab('show'); // Select tab by name if provided in location hash
    $('ul.nav.nav-tabs a[data-toggle="tab"]').on('shown', function (event) {    // Update the location hash to current tab
        window.location.hash= event.target.hash;
    })
});
  • Выберите вкладку по умолчанию (обычно первый)
  • Переключиться на вкладку (если такой элемент действительно присутствует, пусть jQuery обрабатывает его); Ничего не происходит, если указан неправильный хэш
  • [Необязательно] Обновите хеш, если выбрана другая вкладка

Не разрешает прокрутку к запрошенному хешу; но должен это?

8

Это работает в Bootstrap 3 и улучшает ответы на два и более лучших ответов, интегрируя ответ GarciaWebDev (что позволяет параметры url после хеша и прямо из авторов Bootstrap в треевом журнале github):

// Javascript to enable link to tab
var hash = document.location.hash;
var prefix = "tab_";

if (hash) {
    hash = hash.replace(prefix,'');
    var hashPieces = hash.split('?');
    activeTab = $('.nav-tabs a[href=' + hashPieces[0] + ']');
    activeTab && activeTab.tab('show');
} 

// Change hash for page-reload
$('.nav-tabs a').on('shown', function (e) {
    window.location.hash = e.target.hash.replace("#", "#" + prefix);
});
  • 0
    это не работает в Bootstrap 3, 'shown' должно быть 'shown.bs.tab' соответствии с документами: getbootstrap.com/javascript/#tabs-events . Я озадачен тем, почему, но когда я попытался отредактировать ваше сообщение, оно было отклонено ...
6

Этот код выбирает правильную вкладку в зависимости от #hash и добавляет право #hash при нажатии вкладки. (это использует jquery)

В Coffeescript:

$(document).ready ->
    if location.hash != ''
        $('a[href="'+location.hash+'"]').tab('show')

    $('a[data-toggle="tab"]').on 'shown', (e) ->
        location.hash = $(e.target).attr('href').substr(1)

или в JS:

$(document).ready(function() {
    if (location.hash !== '') $('a[href="' + location.hash + '"]').tab('show');
    return $('a[data-toggle="tab"]').on('shown', function(e) {
      return location.hash = $(e.target).attr('href').substr(1);
    });
});
  • 0
    убедитесь, что поставили это после загрузки jquery. Я помещал это в середину страницы (это было легкое место, чтобы вставить это для тестирования), и это не работало. Положить его после загрузки JQuery прекрасно работает.
5

Спасибо, что поделились своими мнениями.

Прочитав все решения. Я придумал решение, которое использует хеш url или localStorage в зависимости от доступности последнего с кодом ниже:

$(function(){
    $(document).on('shown.bs.tab', 'a[data-toggle="tab"]', function (e) {
        localStorage.setItem('activeTab', $(e.target).attr('href'));
    })

    var hash = window.location.hash;
    var activeTab = localStorage.getItem('activeTab');

    if(hash){
          $('#project-tabs  a[href="' + hash + '"]').tab('show');   
    }else if (activeTab){
        $('#project-tabs a[href="' + activeTab + '"]').tab('show');
    }
});
5

@flyffish + @Ztyx решение, которое я использую для вложенных вкладок:

    handleTabLinks();

    function handleTabLinks() {
        if(window.location.hash == '') {
            window.location.hash = window.location.hash + '#_';
        }
        var hash = window.location.hash.split('#')[1];
        var prefix = '_';
        var hpieces = hash.split('/');
        for (var i=0;i<hpieces.length;i++) {
            var domelid = hpieces[i].replace(prefix,'');
            var domitem = $('a[href=#' + domelid + '][data-toggle=tab]');
            if (domitem.length > 0) {
                domitem.tab('show');
            }
        }
        $('a[data-toggle=tab]').on('shown', function (e) {
            if ($(this).hasClass('nested')) {
                var nested = window.location.hash.split('/');
                window.location.hash = nested[0] + '/' + e.target.hash.split('#')[1];
            } else {
                window.location.hash = e.target.hash.replace('#', '#' + prefix);
            }
        });
    }

дети должны иметь class= "вложенные"

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

Этот код с http://github.com/twitter/bootstrap/issues/2415#issuecomment-4450768 работал для меня отлично.

4

Опираясь на решение Demircan Celebi; Я хотел, чтобы вкладка открывалась при изменении URL и открывала вкладку без перезагрузки страницы с сервера.

<script type="text/javascript">
    $(function() {
        openTabHash(); // for the initial page load
        window.addEventListener("hashchange", openTabHash, false); // for later changes to url
    });


    function openTabHash()
    {
        console.log('openTabHash');
        // Javascript to enable link to tab
        var url = document.location.toString();
        if (url.match('#')) {
            $('.nav-tabs a[href="#'+url.split('#')[1]+'"]').tab('show') ;
        } 

        // With HTML5 history API, we can easily prevent scrolling!
        $('.nav-tabs a').on('shown.bs.tab', function (e) {
            if(history.pushState) {
                history.pushState(null, null, e.target.hash); 
            } else {
                window.location.hash = e.target.hash; //Polyfill for old browsers
            }
        })
    }
</script>
4

Я бы посоветовал использовать код, предоставленный авторами Bootstrap, в вопросете трекера на GitHub:

var hash = location.hash
  , hashPieces = hash.split('?')
  , activeTab = $('[href=' + hashPieces[0] + ']');
activeTab && activeTab.tab('show');

Вы можете найти в ссылке на вопрос больше информации о том, почему они не решили поддержать это.

3

Пробовал пару способов, рассмотренных выше, и в итоге получилось следующее рабочее решение, просто скопируйте и вставьте в свой редактор, чтобы попробовать. Чтобы проверить только хэш хэширования на inbox, outbox, составить в url и нажать клавишу ввода.

<html>
    <head>
        <link type='text/css' rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css' />
        <script src="https://code.jquery.com/jquery-2.2.0.min.js"></script>
        <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
    </head>
    <body>
        <div class="container body-content">
            <ul class="nav nav-tabs">
                <li class="active"><a data-toggle="tab" href="#inbox">Inbox</a></li>
                <li><a data-toggle="tab" href="#outbox">Outbox</a></li>
                <li><a data-toggle="tab" href="#compose">Compose</a></li>
            </ul>
            <div class="tab-content">
                <div id="inbox" class="tab-pane fade in active">
                    Inbox Content
                </div>
                <div id="outbox" class="tab-pane fade">
                    Outbox Content
                </div>
                <div id="compose" class="tab-pane fade">
                    Compose Content
                </div>
            </div>
        </div>
        <script>
            $(function () {
                var hash = window.location.hash;
                hash && $('ul.nav a[href="' + hash + '"]').tab('show');
            });
        </script>
    </body>
</html>

Надеюсь, это сэкономит ваше время.

3

Вот что я сделал, действительно простой, и при условии, что ваши ссылки на вкладки имеют связанный с ними идентификатор, вы можете получить атрибут href и передать его функции, отображающей содержимое вкладки:

<script type="text/javascript">
        jQuery(document).ready(function() {
            var hash = document.location.hash;
            var prefix = "tab_";
            if (hash) {
                var tab = jQuery(hash.replace(prefix,"")).attr('href');
                jQuery('.nav-tabs a[href='+tab+']').tab('show');
            }
        });
        </script>

Затем в вашем URL-адресе вы можете добавить хеш как-то вроде: # tab_tab1, часть "tab_" удаляется из самого хеш файла, после чего идентификатор фактической ссылки вкладки в навигационных вкладках (tabid1) помещается после этого, поэтому ваш URL-адрес будет выглядеть примерно так: www.mydomain.com/index.php#tab_tabid1.

Это отлично работает для меня и надеется, что это поможет кому-то другому: -)

2

Мне пришлось изменить некоторые бит, чтобы это работало для меня. Я использую Bootstrap 3 и jQuery 2

// Javascript to enable link to tab
var hash = document.location.hash;
var prefix = "!";
if (hash) {
    hash = hash.replace(prefix,'');
    var hashPieces = hash.split('?');
    activeTab = $('[role="tablist"] a[href=' + hashPieces[0] + ']');
    activeTab && activeTab.tab('show');
}

// Change hash for page-reload
$('[role="tablist"] a').on('shown.bs.tab', function (e) {
    window.location.hash = e.target.hash.replace("#", "#" + prefix);
});
  • 0
    Отличный ответ, кроме меня пришлось заменить на "!" префикс с "tab_". В остальном работал отлично.
2

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

function activateParentTab(tab) {
    $('.tab-pane').each(function() {
        var cur_tab = $(this);
        if ( $(this).find('#' + tab).length > 0 ) {
            $('.nav-tabs a[href=#'+ cur_tab.attr('id') +']').tab('show');
            return false;
        }
    });
}

И можно так назвать (на основе решения @flyffish):

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

// Change hash for page-reload
$('.nav-tabs a').on('shown', function (e) {
    window.location.hash = e.target.hash.replace("#", "#" + prefix);
});

Это решение работает очень хорошо для меня на данный момент. Надеюсь, это может быть полезно для кого-то другого;)

1

Объединяя peices из других ответов, вот решение, которое может открыть много уровней вложенных вкладок:

// opens all tabs down to the specified tab
var hash = location.hash.split('?')[0];
if(hash) {
  var $link = $('[href=' + hash + ']');
  var parents = $link.parents('.tab-pane').get();
  $(parents.reverse()).each(function() {
    $('[href=#' + this.id + ']').tab('show') ;
  });
  $link.tab('show');
}
  • 0
    работает только до 2 уровней вложенности, 3-й уровень вызывает проблемы.
  • 0
    Я только что проверил это на трех уровнях вкладок, и, похоже, это работает для меня. Вы уверены, что это не проблема с вашей реализацией? Какую «проблему» вы испытываете?
Показать ещё 2 комментария
1

У меня была эта проблема, но мне нужно было обрабатывать несколько уровней вкладок. Код довольно уродливый (см. Комментарии), но выполняет свою работу: https://gist.github.com/JensRantil/4721860 Надеюсь, кто-то найдет это полезным (и не стесняйтесь предлагать лучшие решения!).

0

Если это кому-нибудь важно, следующий код небольшой и работает безупречно, чтобы получить единственное значение хеша из URL и показать, что:

<script>
    window.onload = function () {
        let url = document.location.toString();
        let splitHash = url.split("#");
        document.getElementById(splitHash[1]).click();
    };
</script>

он извлекает идентификатор и запускает событие click. Просто.

0

Я делаю что-то вроде этого для ссылок с ajax #!# (Например,/test.com #! # Test3), но вы можете изменить его как угодно

$(document).ready(function() {

       let hash = document.location.hash;
       let prefix = "!#";

       //change hash url on page reload
       if (hash) {
         $('.nav-tabs a[href=\"'+hash.replace(prefix,"")+'\"]').tab('show');
       } 

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

Пример с простой страницей на Github здесь

Ещё вопросы

Сообщество Overcoder
Наверх
Меню