트위터 부트 스트랩 탭 : 페이지 새로 고침 또는 하이퍼 링크의 특정 탭으로 이동


358

Twitter의 Bootstrap Framework 및 해당 Bootstrap Tabs JS를 사용하는 웹 페이지를 개발 중 입니다. 몇 가지 사소한 문제를 제외하고는 효과적입니다. 그 중 하나는 외부 링크에서 특정 탭으로 직접 이동하는 방법을 모릅니다. 예를 들면 다음과 같습니다.

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

외부 페이지에서 링크를 클릭하면 홈 탭과 메모 탭으로 각각 이동해야 합니다.


49
이것이 내장되기를 바랍니다!
데이먼

5
이 질문도 여기에 제기되었습니다 : github.com/twitter/bootstrap/issues/2415 (그리고 거기에 몇 가지 해결책이 있습니다).
Ztyx


1
부트 스트랩 문제에 대한 업데이트 링크는 github.com/twbs/bootstrap/issues/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
window.scrollTo(0, 0);창을 항상 맨 위로 스크롤하기 위해 한 줄 을 더 추가하겠습니다
Trung Lê

1
$ ( '. nav-tabs a [href * = #'+ url.split ( '#') [1] + ']'). tab ( 'show'); // 그렇지 않으면 첫 번째 #에만 일치하기 때문에 *가 더 안전합니다.
mattangriffel

1
나를 위해 일한 온라인 : window.location.hash && $ ( 'li a [href = "'+ window.location.hash + '"]'). tab ( 'show'). trigger ( "click");
Dean Meehan

10
다음은 Bootstrap 3에 대한 데모입니다 : bootply.com/render/VQqzOawoYc#tab2소스 코드
Zim

2
jquery를 1.09에서 1.11로 업그레이드 한 후이 오류가 발생 Syntax error, unrecognized expression: .nav-tabs a[href=#tab-2]합니다. stackoverflow.com/questions/12131273/…를
Pietro Z.

213

최신 정보

부트 스트랩 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>

1
특정 탭 아래에있는 책갈피를 참조하는 간단한 방법이 있습니까? 내 페이지에는 5 개의 탭이 있고 그 아래에는 여러 개의 책갈피가 있습니다. 내가 원하는 것은 이러한 책갈피를 탭 외부에서 링크 가능하게 만드는 것입니다.
nize

@nize 당신이하려는 일로 jsfiddle을 만들면 살펴볼 것입니다.
flynfish

1
다음은 Bootstrap 3의 bootlpy 데모입니다 : bootply.com/render/VQqzOawoYc#tab2소스 코드
Zim

위의 예에는 href에 큰 따옴표가 없습니다. 5 호선 :$('.nav-tabs a[href="'+hash.replace(prefix,"")+'"]').tab('show');
Ponyboy

'yoursite.com/anotherpage/#tab_mytab'에서 마지막 슬래시 (# 이전)를 제거해야한다는 점을 제외하고는 나를 위해 작동합니다. 그렇지 않으면 페이지로드로 인해 혼란을 겪었습니다.
Alexander

52

click해당 탭 링크 에서 이벤트를 트리거 할 수 있습니다 .

$(document).ready(function(){

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

});

팁 고마워! 이것은 하나의 작은 문제로 훌륭하게 작동했습니다. 페이지를 새로 고치면 올바른 탭으로 이동하지 않습니다. Ctrl + F5를 누르면됩니다. 코드를 다음과 같이 수정했다 :`$ (document) .ready (function () {function getUrlVars () {var vars = {}; var parts = window.location.href.replace (/ [? &] + ([ ^ = &] +) = ([^ &] *) / gi, function (m, key, value) {vars [key] = value;}); 반환 vars;} var action = getUrlVars () [ "action" ]; if (action! = "") {$ ( 'a [href = "#'+ action + '"]'). 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 location.hash가 커서 위치를 위아래로 이동시키는 ID로 점프한다는 한 가지 이유 때문에 JS 솔루션보다 솔루션을 선호합니다.
Trung Lê

이 솔루션을 선호합니다. 사실, 활성 클래스를 적절하게 설정하여 탭에 대한 새로운 경로를 만들고 뷰를 다시 생성했습니다. 이렇게하면 페이지 크기 조정, URL 해시 및 페이지 스크롤의 두통을 피할 수 있습니다.
Vijay Meena

10

나는 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;
    })
});
  1. 기본 탭을 선택하십시오 (일반적으로 첫 번째 탭).
  2. 탭으로 전환하십시오 (이러한 요소가있는 경우 jQuery가 처리하도록하십시오). 잘못된 해시가 지정되면 아무 일도 일어나지 않습니다
  3. [선택 사항] 다른 탭을 수동으로 선택한 경우 해시 업데이트

요청 된 해시로 스크롤을 처리하지 않습니다. 하지만 그래야 합니까?



8

이것은 Bootstrap 3에서 작동하며 GarciaWebDev의 답변도 통합하여 dubbe 및 flynfish의 2 가지 최고 답변을 향상시킵니다 (해시 후 URL 매개 변수를 허용하고 github 이슈 추적기의 Bootstrap 제작자가 직접 제공합니다).

// 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
이 부트 스트랩 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를로드 한 후 넣는 것이 좋습니다.
Ron

6

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>


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

어린이에게는 class = "nested"가 있어야합니다.


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

GitHub이슈 트래커에서 Bootstrap 작성자가 제공 한 코드를 사용하는 것이 좋습니다 .

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

문제를 지원하지 않기로 한 이유에 대한 자세한 정보는 문제 링크에서 찾을 수 있습니다.


4

위에서 논의한 몇 가지 방법을 시도하고 다음과 같은 작업 솔루션으로 끝내십시오. 편집기에서 복사하여 붙여 넣기 만하면됩니다. 해시를받은 편지함, 보낼 편지함으로 바꾸고 URL을 작성하고 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>

이것이 당신의 시간을 절약 할 수 있기를 바랍니다.


3

여기에 내가 한 일이 정말 간단하며 탭 링크에 ID가 연결되어 있으면 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)의 실제 탭 링크 ID가이 뒤에 배치됩니다. 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

나는 이것을 위해 약간의 비트를 수정해야했다. 부트 스트랩 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 단계에서는 문제가 발생합니다.
Nicholas Hamilton

방금 세 가지 수준의 탭에 대해 이것을 테스트했으며 제대로 작동하는 것 같습니다. 이것이 구현에 문제가되지 않습니까? 어떤 "문제"가 발생합니까?
cweston

1 단계 및 2 단계의 모든 탭은 제대로 작동하지만 3 단계에서는 페이지를 새로 고치거나 양식을 제출할 때 페이지를 다시 열면 2 단계의 첫 번째 탭에 초점이 맞춰집니다.
Nicholas Hamilton

그래서 잘 작동했습니다 (내 코드에는 약간의 오타가있었습니다), 오타 수정 후 $('.nav-tabs li a').click( function(e) { history.pushState( null, null, $(this).attr('href') );});코드 위의 자바 스크립트 에서만 가능 합니다.
Nicholas Hamilton

1

누군가에게 중요하다면 다음 코드는 작고 완벽하게 작동하여 URL에서 단일 해시 값을 가져 와서 표시합니다.

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

그것이하는 일은 ID를 검색하고 click 이벤트를 발생시키는 것입니다. 단순한.


0

나는 아약스 #!#(예 : / test.com #! # test3) 와의 링크에 대해 sth를 만들지 만 원하는대로 수정할 수 있습니다

$(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-탐색 링크에 클래스 접두사를 사용하고 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.