Bootstrap 3: mantenha a guia selecionada na atualização da página

120

Estou tentando manter a guia selecionada ativa na atualização com o Bootstrap 3 . Tentei e verifiquei com alguma pergunta já foi feita aqui, mas nada de trabalho para mim. Não sei onde estou errado. Aqui está o meu código

HTML

<!-- tabs link -->
<ul class="nav nav-tabs" id="rowTab">
    <li class="active"><a href="#personal-info" data-toggle="tab">Personal Information</a></li>
    <li><a href="#Employment-info" data-toggle="tab">Employment Information</a></li>
    <li><a href="#career-path" data-toggle="tab">Career Path</a></li>
    <li><a href="#warnings" data-toggle="tab">Warning</a></li>
</ul>
<!-- end: tabs link -->

<div class="tab-content">
    <div class="tab-pane active" id="personal-info">
        tab data here...
    </div>

    <div class="tab-pane" id="Employment-info">
        tab data here...
    </div>

    <div class="tab-pane" id="career-path">
        tab data here...
    </div>

    <div class="tab-pane" id="warnings">
        tab data here...
    </div>
</div>

Javascript :

// tab
$('#rowTab a:first').tab('show');

//for bootstrap 3 use 'shown.bs.tab' instead of 'shown' in the next line
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
//save the latest tab; use cookies if you like 'em better:
localStorage.setItem('selectedTab', $(e.target).attr('id'));
});

//go to the latest tab, if it exists:
var selectedTab = localStorage.getItem('selectedTab');
if (selectedTab) {
  $('#'+selectedTab).tab('show');
}
Code Lover
fonte
O motivo pelo qual não está funcionando é porque não está armazenando a guia selecionada. Quando eu fiz console.log("selectedTab::"+selectedTab);, eu tenho: selectedTab::undefined. Portanto, a lógica você aplicou não é correto
O Cavaleiro das Trevas
Então você pode me guiar o que fazer?
Code Lover
Estou tentando consertar isso. Se eu faço, eu vou postar a resposta aqui para você
O Cavaleiro das Trevas
Eu aprecio isso .. obrigado por ajudar ..
Amante do Código
Eu acho que isso vai funcionar: jsbin.com/UNuYoHE/2/edit . Se isso me informar, postarei a resposta de maneira clara. Você também pode querer olhar para os textos da guia div. eles não dão a resposta adequada quando você clica neles. Por exemplo, se você clicar em tab4, receberá o texto tab1.
O Cavaleiro das Trevas

Respostas:

187

Eu prefiro armazenar a guia selecionada no hashvalue da janela. Isso também permite o envio de links para colegas que vêem a mesma página. O truque é alterar o hash do local quando outra guia for selecionada. Se você já usa # em sua página, possivelmente a tag hash deve ser dividida. No meu aplicativo, eu uso ":" como separador de valor de hash.

<ul class="nav nav-tabs" id="myTab">
  <li class="active"><a href="#home">Home</a></li>
  <li><a href="#profile">Profile</a></li>
  <li><a href="#messages">Messages</a></li>
  <li><a href="#settings">Settings</a></li>
</ul>

<div class="tab-content">
  <div class="tab-pane active" id="home">home</div>
  <div class="tab-pane" id="profile">profile</div>
  <div class="tab-pane" id="messages">messages</div>
  <div class="tab-pane" id="settings">settings</div>
</div>

JavaScript, deve ser incorporado após o acima em uma <script>...</script>parte.

$('#myTab a').click(function(e) {
  e.preventDefault();
  $(this).tab('show');
});

// store the currently selected tab in the hash value
$("ul.nav-tabs > li > a").on("shown.bs.tab", function(e) {
  var id = $(e.target).attr("href").substr(1);
  window.location.hash = id;
});

// on load of the page: switch to the currently selected tab
var hash = window.location.hash;
$('#myTab a[href="' + hash + '"]').tab('show');
koppor
fonte
Na seção de script, você deve adicionar um ponto-e-vírgula ao final de e.preventDefault();e$(this).tab('show');
Sean Adams-Hiett
12
Infelizmente, o navegador está pulando para o conteúdo da guia quando você clica nele. Esse é o comportamento padrão quando você define o valor window.location.hash. Uma alternativa pode estar usando push.state, mas você precisa de um polyfill para o IE <= 9. Para mais informações sobre e outras soluções alternativas dar uma olhada em stackoverflow.com/questions/3870057/...
Philipp Michael
3
Existe alguma maneira de impedir a "rolagem falsa" para o id em questão quando clicamos no elemento?
Patrice Poliquin
1
A rolagem deve-se ao ID atribuído às guias. Se você usar IDs semânticos e alterar o hash (ou seja, adicionar prefixo / sufixo), ele não será reconhecido como um ID válido e não ocorrerá rolagem. Expandirá a resposta com isso.
Alex Mazzariol
1
@koppor ele funciona, mas quando pulo diretamente para a outra guia salva (via link), ele exibe a guia inicial ou a primeira guia rapidamente em torno de 1 segundo antes de saltar para a guia no link .. Alguma idéia para impedi-lo de exibir a primeira guia, uma vez que não é necessário?
MBoy
135

Este é o melhor que eu tentei:

$(document).ready(function() {
    if (location.hash) {
        $("a[href='" + location.hash + "']").tab("show");
    }
    $(document.body).on("click", "a[data-toggle='tab']", function(event) {
        location.hash = this.getAttribute("href");
    });
});
$(window).on("popstate", function() {
    var anchor = location.hash || $("a[data-toggle='tab']").first().attr("href");
    $("a[href='" + anchor + "']").tab("show");
});
Xavi Martínez
fonte
20
Este funciona melhor do que a solução aceite (a melhor eu dizer: copiar e colar obras: D)
Cyril Duchon-Doris
3
melhor copiar e colar de sempre: P
Ghostff 04/10/2015
1
Eu acho que mudar o seletor para "a[data-toggle=tab]"seria melhor. A maneira como o seletor é gravado agora também altera o URL do navegador ao clicar em um link para, por exemplo, abrir um modal.
leifdenby
5
Você pode adicionar colchetes no seletor, como 'a [href = "' + location.hash + '"]]'. Tropeçou em um erro de sintaxe.
Asdacap
1
O uso desse tipo como está em conflito com os menus suspensos do Bootstrap (que usam data-toggle="dropdown" . E que por acaso tenho na mesma página com guias em um caso como alguém sugeriu aqui, apenas substituindo $(document.body).on("click", "a[data-toggle]", function(event) {com $(document.body).on("click", "a[data-toggle='tab']", function(event) {fez o truque para mim.
Jiveman
44

Uma mistura entre outras respostas:

  • Nenhum salto ao clicar
  • Economize no hash do local
  • Economize no localStorage (por exemplo: para envio de formulário)
  • Basta copiar e colar;)

    if (location.hash) {
      $('a[href=\'' + location.hash + '\']').tab('show');
    }
    var activeTab = localStorage.getItem('activeTab');
    if (activeTab) {
      $('a[href="' + activeTab + '"]').tab('show');
    }
    
    $('body').on('click', 'a[data-toggle=\'tab\']', function (e) {
      e.preventDefault()
      var tab_name = this.getAttribute('href')
      if (history.pushState) {
        history.pushState(null, null, tab_name)
      }
      else {
        location.hash = tab_name
      }
      localStorage.setItem('activeTab', tab_name)
    
      $(this).tab('show');
      return false;
    });
    $(window).on('popstate', function () {
      var anchor = location.hash ||
        $('a[data-toggle=\'tab\']').first().attr('href');
      $('a[href=\'' + anchor + '\']').tab('show');
    });
inscrição
fonte
1
Pena que eu tentei as outras soluções primeiro - esta funciona melhor!
tdc 24/05
2
Melhor solução que eu tentei de muitas diferentes. O salto para o conteúdo guia era irritante
Kentor
4
Salto conteúdo ainda existe com esta resposta
shazyriver
2
Excelente solução: Copie, cole, vá almoçar. Agradável.
Gary Stanton
1
Melhor solução de todos os tempos
sortudo
19

O código de Xavi estava funcionando totalmente. Porém, ao navegar para outra página, enviar um formulário e ser redirecionado para a página com minhas guias não estava carregando a guia salva.

localStorage para o resgate (código ligeiramente alterado de Nguyen):

$('a[data-toggle="tab"]').click(function (e) {
    e.preventDefault();
    $(this).tab('show');
});

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

var selectedTab = localStorage.getItem('selectedTab');
if (selectedTab != null) {
    $('a[data-toggle="tab"][href="' + selectedTab + '"]').tab('show');
}
apfz
fonte
2
Isto é ouro! Funciona mesmo com modais! Ótima resposta.
Lech Osiński
2
Esse código é fantástico e funciona muito bem se você deseja que a guia permaneça selecionada, mesmo que o usuário saia do site (encerre a sessão) e volte mais tarde. Para que a seleção persista apenas durante a sessão atual e retorne à guia padrão na próxima sessão, substitua as duas instâncias de "localStorage" por "sessionStorage".
Gary.Ray
Solução curta, doce, de copiar / colar que funciona muito bem com o Bootstrap 4. #
CFP Support
Uau solução tremenda!
Jilani Um
1
[data-toggle="pill"]para comprimidos
mxmissile
12

Este usa HTML5 localStoragepara armazenar a guia ativa

$('a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
    localStorage.setItem('activeTab', $(e.target).attr('href'));
});
var activeTab = localStorage.getItem('activeTab');
if (activeTab) {
   $('#navtab-container a[href="' + activeTab + '"]').tab('show');
}

ref: http://www.tutorialrepublic.com/faq/how-to-keep-the-current-tab-active-on-page-reload-in-bootstrap.php https://www.w3schools.com/bootstrap /bootstrap_ref_js_tab.asp

Ajith R Nair
fonte
isso é bom, mas a desvantagem é que você não seria capaz de compartilhar links com aba ativa
lfender6445
isso é bom, a vantagem é que ele não apresenta problema em que "window.location.hash" adiciona valor de hash ao parâmetro de solicitação http no URL, causando colisão e parâmetros inválidos lidos por outros pedidos http, como paginação e etc.
Dung
4

Baseando-me nas respostas fornecidas por Xavi Martínez e koppor , criei uma solução que usa o URL hash ou localStorage, dependendo da disponibilidade do último:

function rememberTabSelection(tabPaneSelector, useHash) {
    var key = 'selectedTabFor' + tabPaneSelector;
    if(get(key)) 
        $(tabPaneSelector).find('a[href=' + get(key) + ']').tab('show');

    $(tabPaneSelector).on("click", 'a[data-toggle]', function(event) {
        set(key, this.getAttribute('href'));
    }); 

    function get(key) {
        return useHash ? location.hash: localStorage.getItem(key);
    }

    function set(key, value){
        if(useHash)
            location.hash = value;
        else
            localStorage.setItem(key, value);
    }
}

Uso:

$(document).ready(function () {
    rememberTabSelection('#rowTab', !localStorage);
    // Do Work...
});

Ele não acompanha o botão Voltar, como é o caso da solução de Xavi Martínez .

Ziad
fonte
4

Meu código, funciona para mim, eu uso localStorageHTML5

$('#tabHistory  a').click(function(e) {
  e.preventDefault();
  $(this).tab('show');
});
$("ul.nav-tabs#tabHistory > li > a").on("shown.bs.tab", function(e) {
  var id = $(e.target).attr("href");
  localStorage.setItem('selectedTab', id)
});
var selectedTab = localStorage.getItem('selectedTab');
$('#tabHistory a[href="' + selectedTab + '"]').tab('show');
Nguyen Pham
fonte
4

Eu tentei isso e funciona: (Substitua isso pela pílula ou guia que você está usando)

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

        // Here, save the index to which the tab corresponds. You can see it 
        // in the chrome dev tool.
        var activeTab = localStorage.getItem('activeTab');

        // In the console you will be shown the tab where you made the last 
        // click and the save to "activeTab". I leave the console for you to 
        // see. And when you refresh the browser, the last one where you 
        // clicked will be active.
        console.log(activeTab);

        if (activeTab) {
           jQuery('a[href="' + activeTab + '"]').tab('show');
        }
    });

Espero que ajude alguém.

Aqui está o resultado: https://jsfiddle.net/neilbannet/ego1ncr5/5/

Neil Bannet
fonte
4

Bem, isso já está em 2018, mas acho que é melhor tarde do que nunca (como um título em um programa de TV), lol. Aqui embaixo está o código jQuery que eu crio durante minha tese.

<script type="text/javascript">
$(document).ready(function(){
    $('a[data-toggle="tab"]').on('show.affectedDiv.tab', function(e) {
        localStorage.setItem('activeTab', $(e.target).attr('href'));
    });
    var activeTab = localStorage.getItem('activeTab');
    if(activeTab){
        $('#myTab a[href="' + activeTab + '"]').tab('show');
    }
});
</script>

e aqui está o código para as guias de inicialização:

<div class="affectedDiv">
    <ul class="nav nav-tabs" id="myTab">
        <li class="active"><a data-toggle="tab" href="#sectionA">Section A</a></li>
        <li><a data-toggle="tab" href="#sectionB">Section B</a></li>
        <li><a data-toggle="tab" href="#sectionC">Section C</a></li>
    </ul>
    <div class="tab-content">
        <div id="sectionA" class="tab-pane fade in active">
            <h3>Section A</h3>
            <p>Aliquip placeat salvia cillum iphone. Seitan aliquip quis cardigan american apparel, butcher voluptate nisi qui. Raw denim you probably haven't heard of them jean shorts Austin. Nesciunt tofu stumptown aliqua, retro synth master cleanse. Mustache cliche tempor, williamsburg carles vegan helvetica. Reprehenderit butcher retro keffiyeh dreamcatcher synth.</p>
        </div>
        <div id="sectionB" class="tab-pane fade">
            <h3>Section B</h3>
            <p>Vestibulum nec erat eu nulla rhoncus fringilla ut non neque. Vivamus nibh urna, ornare id gravida ut, mollis a magna. Aliquam porttitor condimentum nisi, eu viverra ipsum porta ut. Nam hendrerit bibendum turpis, sed molestie mi fermentum id. Aenean volutpat velit sem. Sed consequat ante in rutrum convallis. Nunc facilisis leo at faucibus adipiscing.</p>
        </div>
        <div id="sectionC" class="tab-pane fade">
            <h3>Section C</h3>
            <p>Vestibulum nec erat eu nulla rhoncus fringilla ut non neque. Vivamus nibh urna, ornare id gravida ut, mollis a magna. Aliquam porttitor condimentum nisi, eu viverra ipsum porta ut. Nam hendrerit bibendum turpis, sed molestie mi fermentum id. Aenean volutpat velit sem. Sed consequat ante in rutrum convallis. Nunc facilisis leo at faucibus adipiscing.</p>
        </div>
    </div>
</div>


Não se esqueça de chamar o bootstrap e outras coisas fundamentais 

Aqui estão os códigos rápidos para você:

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>


Agora vamos à explicação:

O código jQuery no exemplo acima simplesmente obtém o valor do atributo href do elemento quando uma nova guia é mostrada usando o método jQuery .attr () e salva-o localmente no navegador do usuário através do objeto localStorage HTML5. Posteriormente, quando o usuário atualiza a página, recupera esses dados e ativa a guia relacionada pelo método .tab ('show').

Procurando alguns exemplos? aqui está um para vocês .. https://jsfiddle.net/Wineson123/brseabdr/

Eu gostaria que minha resposta pudesse ajudar a todos .. Cheerio! :)

Mr. Winson
fonte
2

Como ainda não posso comentar, copiei a resposta de cima, isso realmente me ajudou. Mas eu mudei para trabalhar com cookies em vez de #id, então eu queria compartilhar as alterações. Isso torna possível armazenar a guia ativa por mais tempo do que apenas uma atualização (por exemplo, redirecionamento múltiplo) ou quando o ID já está sendo usado e você não deseja implementar o método de divisão koppors.

<ul class="nav nav-tabs" id="myTab">
    <li class="active"><a href="#home">Home</a></li>
    <li><a href="#profile">Profile</a></li>
    <li><a href="#messages">Messages</a></li>
    <li><a href="#settings">Settings</a></li>
</ul>

<div class="tab-content">
    <div class="tab-pane active" id="home">home</div>
    <div class="tab-pane" id="profile">profile</div>
    <div class="tab-pane" id="messages">messages</div>
    <div class="tab-pane" id="settings">settings</div>
</div>

<script>
$('#myTab a').click(function (e) {
    e.preventDefault();
    $(this).tab('show');
});

// store the currently selected tab in the hash value
$("ul.nav-tabs > li > a").on("shown.bs.tab", function (e) {
    var id = $(e.target).attr("href").substr(1);
    $.cookie('activeTab', id);
});

    // on load of the page: switch to the currently selected tab
    var hash = $.cookie('activeTab');
    if (hash != null) {
        $('#myTab a[href="#' + hash + '"]').tab('show');
    }
</script>
Joeri Landman
fonte
Obrigado pela atualização. Na realidade, eu estava procurando por uma solução desse tipo, mas, além do tempo que queria, recebi apenas a resposta @koppor como uma solução. Na verdade, essa é uma das melhores maneiras de usar o recurso de volta. Obrigado pela atualização
Code Lover
2

Eu tentei o código oferecido por Xavi Martínez . Funcionou, mas não para o IE7. O problema é: as guias não se referem a nenhum conteúdo relevante.
Então, eu prefiro esse código para resolver esse problema.

function pageLoad() {
  $(document).ready(function() {

    var tabCookieName = "ui-tabs-1"; //cookie name
    var location = $.cookie(tabCookieName); //take tab's href

    if (location) {
      $('#Tabs a[href="' + location + '"]').tab('show'); //activate tab
    }

    $('#Tabs a').click(function(e) {
      e.preventDefault()
      $(this).tab('show')
    })

    //when content is alredy shown - event activate 
    $('#Tabs a').on('shown.bs.tab', function(e) {
      location = e.target.hash; // take current href
      $.cookie(tabCookieName, location, {
        path: '/'
      }); //write href in cookie
    })
  });
};
Vitalii Isaenko
fonte
isso é bom, mas a desvantagem é que você não seria capaz de compartilhar links com aba ativa
lfender6445
1

Obrigado por compartilhar.

Ao ler todas as soluções. Eu vim com uma solução que usa o URL hash ou localStorage, dependendo da disponibilidade deste último com o código abaixo:

$(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');
    }
});
Vaibhav
fonte
1

Para o Bootstrap v4.3.1. Tente abaixo:

$(document).ready(function() {
    var pathname = window.location.pathname; //get the path of current page
    $('.navbar-nav > li > a[href="'+pathname+'"]').parent().addClass('active');
})
gkc123
fonte
0

Usando html5, preparei este:

Alguns estão na página:

<h2 id="heading" data-activetab="@ViewBag.activetab">Some random text</h2>

A viewbag deve conter apenas o ID da página / elemento, por exemplo: "testing"

Criei um site.js e adicionei o script na página:

/// <reference path="../jquery-2.1.0.js" />
$(document).ready(
  function() {
    var setactive = $("#heading").data("activetab");
    var a = $('#' + setactive).addClass("active");
  }
)

Agora tudo o que você precisa fazer é adicionar seus IDs à ​​sua barra de navegação. Por exemplo.:

<ul class="nav navbar-nav">
  <li **id="testing" **>
    @Html.ActionLink("Lalala", "MyAction", "MyController")
  </li>
</ul>

Todos saudam o atributo de dados :)

Theodor Alexander Hkansson Hei
fonte
0

Além da resposta de Xavi Martínez, evitando o salto no clique

Evitando o salto

$(document).ready(function(){

    // show active tab

    if(location.hash) {

        $('a[href=' + location.hash + ']').tab('show');
    }

    // set hash on click without jumb

    $(document.body).on("click", "a[data-toggle]", function(e) {

        e.preventDefault();

        if(history.pushState) {

            history.pushState(null, null, this.getAttribute("href"));
        }
        else {

            location.hash = this.getAttribute("href");
        }

        $('a[href=' + location.hash + ']').tab('show');

        return false;
    });
});

// set hash on popstate

$(window).on('popstate', function() {

    var anchor = location.hash || $("a[data-toggle=tab]").first().attr("href");

    $('a[href=' + anchor + ']').tab('show');
});

Guias aninhadas

implementação com o caractere "_" como separador

$(document).ready(function(){

    // show active tab

    if(location.hash) {

        var tabs = location.hash.substring(1).split('_');

        $.each(tabs,function(n){

            $('a[href=#' + tabs[n] + ']').tab('show');
        });         

        $('a[href=' + location.hash + ']').tab('show');
    }

    // set hash on click without jumb

    $(document.body).on("click", "a[data-toggle]", function(e) {

        e.preventDefault();

        if(history.pushState) {

            history.pushState(null, null, this.getAttribute("href"));
        }
        else {

            location.hash = this.getAttribute("href");
        }

        var tabs = location.hash.substring(1).split('_');

        //console.log(tabs);

        $.each(tabs,function(n){

            $('a[href=#' + tabs[n] + ']').tab('show');
        });

        $('a[href=' + location.hash + ']').tab('show');

        return false;
    });
});

// set hash on popstate

$(window).on('popstate', function() {

    var anchor = location.hash || $("a[data-toggle=tab]").first().attr("href");

    var tabs = anchor.substring(1).split('_');

    $.each(tabs,function(n){

        $('a[href=#' + tabs[n] + ']').tab('show');
    });

    $('a[href=' + anchor + ']').tab('show');
});
RafaSashi
fonte
0

Usamos o gatilho jquery para carregar um script, pressione o botão para nós

$ (". class_name"). trigger ('clique');

Dan Kaiser
fonte
0

Ai, há muitas maneiras de fazer isso. Eu vim com isso, curto e simples. Espero que isso ajude os outros.

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

  $('.nav-tabs a').on('shown.bs.tab', function (e) {
    window.location.hash = e.target.hash;
    if(e.target.hash == "#activity"){
      $('.nano').nanoScroller();
    }
  })
user752746
fonte
0

Existe uma solução após recarregar a página e manter a guia esperada conforme selecionada.

Suponha que, após salvar os dados, o URL redirecionado seja: my_url # tab_2

Agora, através do script a seguir, sua guia esperada permanecerá selecionada.

$(document).ready(function(){
    var url = document.location.toString();
    if (url.match('#')) {
        $('.nav-tabs a[href="#' + url.split('#')[1] + '"]').tab('show');
        $('.nav-tabs a').removeClass('active');
    }
});
Hasib Kamal
fonte
A classe ativa é automaticamente atribuída à tag anchor, portanto é removida por $ ('. Nav-tabs a'). RemoveClass ('active'); esse script.
Hasib Kamal