Các tab Bootstrap của Twitter: Chuyển đến Tab cụ thể trên Tải lại trang hoặc siêu liên kết


358

Tôi đang phát triển một trang web trong đó tôi đang sử dụng Bootstrap Framework của Twitter và của họ JS Bootstrap Tab . Nó hoạt động rất tốt ngoại trừ một vài vấn đề nhỏ, một trong số đó là tôi không biết cách truy cập trực tiếp vào một tab cụ thể từ một liên kết bên ngoài. Ví dụ:

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

nên chuyển đến tab Trang chủ và tab Ghi chú tương ứng khi nhấp vào liên kết từ trang bên ngoài


49
muốn điều này được xây dựng trong!
Damon

5
Câu hỏi này cũng đã được đưa ra ở đây: github.com/twitter/bootstrap/issues/2415 (và có một vài giải pháp ở đó).
Ztyx

điều này đã giúp tôi -> stackoverflow.com/questions/12131273/ từ
JGilmartin

1
Liên kết được cập nhật cho vấn đề bootstrap là github.com/twbs/bootstrap/issues/2415
bmihelac

3

Câu trả lời:


603

Đây là giải pháp của tôi cho vấn đề, có lẽ hơi muộn. Nhưng nó có thể giúp người khác:

// 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
Tôi muốn thêm 1 dòng nữa window.scrollTo(0, 0);để đảm bảo Cửa sổ luôn cuộn lên trên cùng
Trung Lê

1
$ ('. nav-tab a [href * = #' + url.split ('#') [1] + ']'). tab ('hiển thị'); // Với một * an toàn hơn vì nếu không, nó chỉ khớp với # ... đầu tiên
mattangriffel

1
Trực tuyến phù hợp với tôi: window.location.hash && $ ('li a [href = "' + window.location.hash + '"]'). Tab ('show'). Trigger ("click");
Dean Meehan

10
Đây là bản demo cho Bootstrap 3: bootply.com/render/VQqzOawoYc#tab2mã nguồn
Zim

2
Sau khi nâng cấp jquery lên 1.11 từ 1.09, tôi gặp lỗi này : Syntax error, unrecognized expression: .nav-tabs a[href=#tab-2]. Đã giải quyết bằng stackoverflow.com/questions/12131273/ Khăn
Pietro Z.

213

CẬP NHẬT

Đối với Bootstrap 3, hãy đổi .on('shown', ...)thành.on('shown.bs.tab', ....)


Điều này dựa trên câu trả lời @dubbe và câu trả lời SO này được chấp nhận . Nó xử lý vấn đề với window.scrollTo(0,0)không hoạt động chính xác. Vấn đề là khi bạn thay thế băm url trên tab được hiển thị, trình duyệt sẽ cuộn đến hàm băm đó vì nó là một thành phần trên trang. Để giải quyết vấn đề này, hãy thêm tiền tố để hàm băm không tham chiếu phần tử trang thực tế

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

Ví dụ sử dụng

Nếu bạn có tab-pane với id = "mytab", bạn cần đặt liên kết của mình như thế này:

<a href="yoursite.com/#tab_mytab">Go to Specific Tab </a>

1
Sẽ có một cách đơn giản để tham chiếu các dấu trang nằm dưới một tab cụ thể? Tôi có năm tab trên trang của mình và trong số đó tôi có một số dấu trang. Những gì tôi muốn là làm cho các dấu trang này có thể liên kết từ bên ngoài tab.
nize

@nize nếu bạn tạo một jsfiddle với những gì bạn đang cố gắng tôi sẽ cố gắng xem xét.
cá chuồn

1
Đây là bản demo Bootlpy cho Bootstrap 3: bootply.com/render/VQqzOawoYc#tab2mã nguồn
Zim

Ví dụ trên thiếu dấu ngoặc kép trên href. dòng 5 nên là:$('.nav-tabs a[href="'+hash.replace(prefix,"")+'"]').tab('show');
Ponyboy

Hoạt động với tôi ngoại trừ việc tôi phải xóa dấu gạch chéo chuyển tiếp cuối cùng (trước dấu #) trong 'yoursite.com/anotherpage/#tab_mytab' nếu không nó đã chơi havoc khi tải trang.
Alexander

52

bạn có thể kích hoạt một clicksự kiện trên liên kết tab tương ứng:

$(document).ready(function(){

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

});

Cảm ơn vì tiền hỗ trợ! Điều này làm việc tuyệt vời với một vấn đề nhỏ. Làm mới trang, sẽ không đưa nó đến đúng tab. Nhấn Ctrl + F5 sẽ. Tôi đã sửa đổi mã thành như sau: `$ (document). Yet (function () {function getUrlVars () {var vars = {}; var part = window.location.href.replace (/ [? &] + ([ ^ = &] +) = ([^ &] *) / gi, hàm (m, key, value) {vars [key] = value;}); return vars;} var action = getUrlVars () ["action" ]; if (hành động! = "") {$ ('a [href = "#' + hành động + '"]'). click ()};}); `
mraliks

44

Đây là một triển khai cải tiến của giải pháp dubbe ngăn chặn cuộn.

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

Mặc dù giải pháp JavaScript được cung cấp có thể hoạt động, tôi đã đi một cách hơi khác không yêu cầu JavaScript bổ sung, nhưng yêu cầu logic theo quan điểm của bạn. Bạn tạo một liên kết với một tham số URL tiêu chuẩn, như:

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

Sau đó, bạn chỉ cần phát hiện giá trị của activeTab để viết 'class = "active"' trong phần thích hợp <li>

Mã giả (thực hiện theo ngôn ngữ của bạn). Lưu ý Tôi đã đặt tab 'home' làm hoạt động mặc định nếu không có tham số nào được cung cấp trong ví dụ này.

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

Tôi thích giải pháp của bạn hơn cho giải pháp JS vì một lý do đơn giản là vị trí JS.hash sẽ nhảy đến ID khiến vị trí của con trỏ đi lên và xuống.
Trung Lê

Tôi thích giải pháp này. Trong thực tế, tôi đã tạo các tuyến mới cho các tab và chế độ xem được tạo lại bằng cách đặt lớp hoạt động tương ứng. Điều này tránh đau đầu thay đổi kích thước trang, băm url và cuộn trang cùng nhau.
Vijay Meena

10

Tôi không phải là một fan hâm mộ lớn của nếu ... khác; vì vậy tôi đã thực hiện một cách tiếp cận đơn giản hơn.

$(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. Chọn một tab mặc định (thường là đầu tiên)
  2. Chuyển sang tab (nếu một phần tử như vậy thực sự có mặt; hãy để jQuery xử lý nó); Không có gì xảy ra nếu băm sai được chỉ định
  3. [Tùy chọn] Cập nhật hàm băm nếu một tab khác được chọn thủ công

Không giải quyết việc cuộn đến hàm băm được yêu cầu; Nhưng có nên không?



8

Điều này hoạt động trong Bootstrap 3 và cải thiện 2 câu trả lời hàng đầu của dubbe và flynfish bằng cách tích hợp câu trả lời của GarciaWebDev (cho phép các tham số url sau hàm băm và trực tiếp từ các tác giả Bootstrap trên trình theo dõi vấn đề 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);
});

1
điều này không hoạt động trong Bootstrap 3, 'shown'nên 'shown.bs.tab'theo tài liệu: getbootstrap.com/javascript/#tabs-events . Tôi gặp khó khăn về lý do tại sao nhưng khi tôi cố gắng chỉnh sửa bài đăng của mình thì nó đã bị từ chối ...
YPCrumble

6

Mã này chọn tab bên phải tùy thuộc vào #hash và thêm #hash đúng khi nhấp vào tab. (cái này sử dụng jquery)

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

hoặc trong 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);
    });
});

hãy chắc chắn để đặt cái này sau khi jquery đã tải. Tôi đã đặt nó ở giữa một trang (đó là một nơi dễ dàng để chèn nó để thử nghiệm) và nó không hoạt động. Đặt nó sau khi tôi tải jquery hoạt động tuyệt vời.
Ron

6

Xây dựng dựa trên giải pháp của Demircan Celebi's; Tôi muốn tab mở khi sửa đổi url và mở tab mà không phải tải lại trang từ máy chủ.

<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 + Giải pháp @Ztyx mà tôi sử dụng cho các tab lồng nhau:

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

trẻ em nên có lớp = "lồng"


5

Tôi đã đưa ra một giải pháp sử dụng hàm băm url hoặc localStorage tùy thuộc vào tính khả dụng của mã sau với mã dưới đây:

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

Tôi sẽ đề nghị bạn sử dụng mã được cung cấp bởi các tác giả Bootstrap trên trình theo dõi vấn đề của họ trên GitHub :

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

Bạn có thể tìm thấy trên đường dẫn đến vấn đề thêm thông tin về lý do tại sao họ không chọn hỗ trợ điều đó.


4

Đã thử một vài cách được thảo luận ở trên và kết thúc với giải pháp làm việc sau đây, chỉ cần sao chép và dán vào trình chỉnh sửa của bạn để thử. Để kiểm tra, chỉ cần thay đổi hàm băm thành hộp thư đến, hộp thư đi, soạn url và nhấn phím enter.

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

Hy vọng điều này sẽ tiết kiệm thời gian của bạn.


3

Đây là những gì tôi đã làm, thực sự đơn giản và với điều kiện các liên kết tab của bạn có ID được liên kết với chúng, bạn có thể lấy thuộc tính href và chuyển nó sang chức năng hiển thị nội dung tab:

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

Sau đó, trong url của bạn, bạn có thể thêm băm dưới dạng: # tab_tab1, phần 'tab_' được xóa khỏi chính hàm băm để ID của liên kết tab thực tế trong tab điều hướng (tabid1) được đặt sau phần này, vì vậy url sẽ trông giống như: www.mydomain.com/index.php#tab_tabid1.

Điều này hoạt động hoàn hảo đối với tôi và hy vọng nó sẽ giúp người khác :-)


2

Đây là giải pháp của tôi để xử lý các tab lồng nhau. Tôi vừa thêm một chức năng để kiểm tra xem tab hoạt động có tab cha được kích hoạt hay không. Đây là chức năng:

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

Và có thể được gọi như thế này (Dựa trên giải pháp của @ 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);
});

Giải pháp này hoạt động khá tốt với tôi vào lúc này. Hy vọng điều này có thể hữu ích cho người khác;)


2

Tôi đã phải sửa đổi một số bit cho điều này để làm việc cho tôi. Tôi đang sử dụng Bootstrap 3 và 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);
});

Câu trả lời tuyệt vời, ngoại trừ tôi phải thay thế "!" tiền tố với "tab_". Nếu không thì làm việc hoàn hảo.
koziez

2

Chỉ cần chèn mã này trên trang của bạn:

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

Tôi chỉ gặp vấn đề này, nhưng cần xử lý nhiều cấp độ tab. Mã này khá xấu (xem bình luận), nhưng thực hiện công việc của nó: https://gist.github.com/JensRantil/4721860 Hy vọng rằng ai đó sẽ thấy nó hữu ích (và thoải mái đề xuất các giải pháp tốt hơn!).


1

Kết hợp các mẫu từ các câu trả lời khác, đây là một giải pháp có thể mở nhiều cấp độ của các tab lồng nhau:

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

Chỉ hoạt động đến 2 cấp độ lồng, cấp 3 gây ra vấn đề.
Nicholas Hamilton

Tôi vừa thử nghiệm điều này với ba cấp độ của tab và nó dường như đang hoạt động với tôi. Bạn có chắc chắn đây không phải là vấn đề với việc triển khai của bạn? Những vấn đề bạn đang gặp là gì?
cernon

Bất kỳ tab nào ở cấp 1 và cấp 2 đều hoạt động tốt, tuy nhiên, ở cấp 3, khi làm mới trang (hoặc gửi biểu mẫu), khi trang mở lại, nó sẽ tập trung vào tab đầu tiên ở cấp 2.
Nicholas Hamilton

Vì vậy, làm cho nó hoạt động tốt (có một lỗi đánh máy nhỏ trong mã của tôi), tuy nhiên sau khi sửa lỗi chính tả, chỉ với $('.nav-tabs li a').click( function(e) { history.pushState( null, null, $(this).attr('href') );});javascript trên mã của bạn.
Nicholas Hamilton

1

Nếu nó quan trọng với bất kỳ ai, đoạn mã sau nhỏ và hoạt động hoàn hảo, để có được một giá trị băm duy nhất từ ​​URL và cho thấy:

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

những gì nó làm là nó lấy id và kích hoạt sự kiện click. Đơn giản.


0

Tôi tạo sth như thế này cho các liên kết với ajax #!#(ví dụ / test.com #! # Test3) nhưng bạn có thể sửa đổi bất cứ điều gì bạn thích

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

Ví dụ với trang đơn giản trên Github tại đây


0

Tôi biết chủ đề này rất cũ, nhưng tôi sẽ rời khỏi đây để thực hiện:

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

Lưu ý rằng tôi đang sử dụng nav-tiền tố lớp để liên kết điều hướng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.