Вкладки завантаження Twitter: перейдіть до певної вкладки для перезавантаження сторінки або гіперпосилання


358

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

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

слід перейти на вкладку Домашня сторінка та вкладку Примітки відповідно при натисканні на посилання із зовнішньої сторінки


49
Бажаю, щоб це було вбудовано!
Деймон

5
Це питання також було порушено тут: github.com/twitter/bootstrap/isissue/2415 (і там є пара рішень).
Ztyx

це допомогло мені -> stackoverflow.com/questions/12131273 / ...
JGilmartin

1
Оновлене посилання на випуск завантажувальної програми - github.com/twbs/bootstrap/isissue/2415
bmihelac

3
Плагін, що виправляє це: github.com/timabell/jquery.stickytabs
Tim Abell

Відповіді:


603

Ось моє рішення проблеми, можливо, трохи пізно, можливо. Але це може допомогти іншим:

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

83
Я б додав ще 1 додатковий рядок, window.scrollTo(0, 0);щоб переконатися, що Вікно завжди прокручується доверху
Trung Lê

1
$ ('. nav-tabs a [href * = #' + url.split ('#') [1] + ']'). вкладка ('show'); // З * безпечніше, оскільки в іншому випадку він відповідає лише першому # ...
mattangriffel

1
Інтернет, який працював на мене: window.location.hash && $ ('li a [href = "' + window.location.hash + '"]'). Tab ('show'). Тригер ("клацання");
Дін Мейхан

10
Ось демонстрація Bootstrap 3: bootply.com/render/VQqzOawoYc#tab2 та вихідний код
Zim

2
Після поновлення JQuery до 1,11 з 1,09 я отримую цю помилку: Syntax error, unrecognized expression: .nav-tabs a[href=#tab-2]. Вирішено за допомогою stackoverflow.com/questions/12131273/…
Pietro Z.

213

ОНОВЛЕННЯ

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


Це ґрунтується на відповіді @dubbe і на цій ТАК прийнятій відповіді . Це вирішує проблему, якщо вона 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>

1
Чи буде простий спосіб посилатися на закладки, які знаходяться на певній вкладці? На своїй сторінці у мене п'ять вкладок, а під ними я маю ряд закладок. Мені б хотілося, щоб ці закладки були пов’язані поза вкладкою.
nize

@nize, якщо ви створюєте jsfiddle з тим, що ви намагаєтесь зробити, я спробую поглянути.
мухомор

1
Ось демонстрація Bootlpy для Bootstrap 3: bootply.com/render/VQqzOawoYc#tab2 та вихідний код
Zim

У наведеному вище прикладі відсутні подвійні лапки на href. рядок 5 повинен бути:$('.nav-tabs a[href="'+hash.replace(prefix,"")+'"]').tab('show');
Понібой

Працює для мене, за винятком того, що мені довелося видалити останню проділ вперед (до #) у "yoursite.com/anotherpage/#tab_mytab", інакше він зіграв хаос із завантаженням сторінки.
Олександр

52

ви можете викликати clickподію на відповідному вкладці:

$(document).ready(function(){

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

});

Дякую за пораду! Це чудово спрацювало з однією невеликою проблемою. Оновлення сторінки не перенесе її на правильну вкладку. Якщо натиснути Ctrl + F5, Я змінив код на наступне: `$ (document) .ready (function () {функція getUrlVars () {var vars = {}; var parts = window.location.href.replace (/ [? &] + ([ ^ = &] +) = ([^ &] *) / gi, функція (m, ключ, значення) {vars [key] = value;}); return vars;} var action = getUrlVars () ["дія" ]; if (дія! = "") {$ ('a [href = "#' + дія + '"]'). click ()};}); `
mraliks

44

Це вдосконалена реалізація рішення 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
    }
})

21

Хоча надане рішення JavaScript може працювати, я пішов дещо іншим шляхом, який не потребує додаткового JavaScript, але для вас потрібна логіка. Ви створюєте посилання зі стандартним параметром URL-адреси, наприклад:

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

Тоді ви просто виявите значення activeTab, щоб написати "class =" active "'у відповідному <li>

Псевдокод (реалізуйте відповідно своєю мовою). Примітка. Вкладка "домашня сторінка" встановлена ​​як активна за замовчуванням, якщо в цьому прикладі не вказано жодного параметра.

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

Я віддаю перевагу вашому рішенню рішення JS через одну просту причину в тому, що JS location.hash перескочить до ідентифікатора, що викликає положення курсору вгору і вниз.
Trung Lê

Я вважаю за краще це рішення. Насправді, я створив нові маршрути для вкладок і заново створив перегляд, встановивши відповідно активний клас. Це дозволяє уникнути головного болю щодо зміни розміру сторінок, URL-хешу та прокрутки сторінки разом.
Vijay Meena

10

Я не є великим шанувальником, якщо ... ще; тому я взяв простіший підхід.

$(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;
    })
});
  1. Виберіть вкладку за замовчуванням (зазвичай першу)
  2. Перейдіть на вкладку (якщо такий елемент дійсно присутній; нехай jQuery обробляє його); Нічого не відбувається, якщо вказано неправильний хеш
  3. [Необов’язково] Оновіть хеш, якщо іншу вкладку обрано вручну

Не адресує прокрутку до запитуваного хешу; але чи варто ?



8

Це працює в Bootstrap 3 і покращує дублі та 2 перших відповідей, інтегруючи відповідь GarciaWebDev (що дозволяє встановлювати параметри url після хеша і прямо від авторів Bootstrap у трекері github issue):

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

1
це не працює в Bootstrap 3, 'shown'має 'shown.bs.tab'відповідати документам: getbootstrap.com/javascript/#tabs-events . Мене бентежить, чому, але коли я намагався редагувати вашу публікацію, її відхилили ...
YPCrumble

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

переконайтеся, що ставити це після завантаження jquery. Я розміщував її в середині сторінки (це було просте місце, щоб вставити її для тестування), і це не спрацювало. Поміщення його після завантаження jquery чудово працює.
Рон

6

Спираючись на рішення Демірчана Селебі; Я хотів, щоб вкладка відкривалася під час зміни 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>


5

@flynfish + @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);
            }
        });
    }

у дітей повинен бути клас = "вкладений"


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

4

Я б запропонував вам скористатися кодом, наданим авторами Bootstrap у своєму трекері випусків на GitHub :

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

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


4

Спробував пару способів, обговорених вище, і закінчилося наступне робоче рішення, просто скопіюйте та вставте у свій редактор, щоб спробувати. Щоб перевірити, просто поміняйте хеш на папку "Вхідні", "Вихідні", складіть у 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_' видаляється із самого хешу, тому ідентифікатор фактичної посилання на вкладку у navi-tabs (tabid1) буде розміщений після цього, тож ваш URL виглядатиме приблизно так: www.mydomain.com/index.php#tab_tabid1.

Це ідеально підходить для мене і сподіваюся, що це допоможе комусь іншому :-)


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

І можна назвати так (На основі рішення @ flynfish):

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

На даний момент це рішення працює досить добре для мене. Сподіваюся, це може бути корисним для когось іншого;)


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

Чудова відповідь, хіба що мені довелося замінити "!" префікс з "tab_". Інакше спрацював ідеально.
koziez

2

Просто вставте цей код на свою сторінку:

$(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();
    window.location.hash = this.hash;
    $('html,body').scrollTop(scrollmem);
  });
});


1

Щойно у мене виникла ця проблема, але вона потрібна для обробки кількох рівнів вкладок. Код досить некрасивий (див. Коментарі), але робить свою роботу: https://gist.github.com/JensRantil/4721860 Сподіваємось, хтось інший вважатиме це корисним (і сміливо пропонувати кращі рішення!).


1

Поєднуючи підказки з інших відповідей, ось рішення, яке може відкрити багато рівнів вкладених вкладок:

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

працює лише на 2 рівні гніздування, 3-й рівень викликає проблеми.
Ніколас Гамільтон

Я просто перевірив це на трьох рівнях вкладок, і, здається, він працює для мене. Ви впевнені, що це не проблема вашої реалізації? Яку "проблему" ви відчуваєте?
cweston

Будь-яка вкладка 1-го і 2-го рівня працює чудово, однак на 3-му рівні, при оновленні сторінки (або надсиланні форми), коли сторінка повторно відкривається, фокус надається першій вкладці на 2-му рівні.
Ніколас Гамільтон

Так у нього все нормально (у моєму коді була незначна помилка друку), проте після виправлення помилки, лише з $('.nav-tabs li a').click( function(e) { history.pushState( null, null, $(this).attr('href') );});javascript над вашим кодом.
Ніколас Гамільтон

1

Якщо це важливо для когось, наступний код невеликий і працює бездоганно, щоб отримати єдине хеш-значення з URL-адреси та показати, що:

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

що він робить, це отримує ідентифікатор і запускає подію натискання. Простий.


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


0

Я знаю, що ця тема дуже стара, але я залишу тут свою власну реалізацію:

$(function () {
  // some initialization code

  addTabBehavior()
})

// Initialize events and change tab on first page load.
function addTabBehavior() {
  $('.nav-tabs a').on('show.bs.tab', e => {
    window.location.hash = e.target.hash.replace('nav-', '')
  })

  $(window).on('popstate', e => {
    changeTab()
  })

  changeTab()
}

// Change the current tab and URL hash; if don't have any hash
// in URL, so activate the first tab and update the URL hash.
function changeTab() {
  const hash = getUrlHash()

  if (hash) {
    $(`.nav-tabs a[href="#nav-${hash}"]`).tab('show')
  } else {
    $('.nav-tabs a').first().tab('show')
  }
}

// Get the hash from URL. Ex: www.example.com/#tab1
function getUrlHash() {
  return window.location.hash.slice(1)
}

Зауважте, що я використовую nav-префікс класу для навігаційних посилань.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.