Bootstrap 3: mantener la pestaña seleccionada en la actualización de la página

120

Estoy tratando de mantener activa la pestaña seleccionada al actualizar con Bootstrap 3 . Intenté y verifiqué con algunas preguntas que ya se hicieron aquí, pero ninguna de trabajo para mí. No sé dónde me equivoco. Aqui esta mi codigo

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');
}
Amante del código
fuente
La razón por la que no funciona es porque no almacena la pestaña seleccionada. Cuando lo hice console.log("selectedTab::"+selectedTab);, llegué: selectedTab::undefined. Entonces, la lógica que aplicó no es correcta
The Dark Knight
Entonces, ¿puedes guiarme sobre qué hacer?
Code Lover
Estoy intentando arreglarlo. Si lo hago, publicaré la respuesta aquí para ti
The Dark Knight
Aprecio eso .. gracias por ayudar ..
Code Lover
Creo que esto funcionará: jsbin.com/UNuYoHE/2/edit . Si me lo hace saber, publicaré la respuesta de manera nítida. También es posible que desee ver los textos de la pestaña div. no dan la respuesta adecuada cuando hace clic en ellos. Por ejemplo, si hace clic en tab4, obtendrá el texto tab1.
The Dark Knight

Respuestas:

187

Prefiero almacenar la pestaña seleccionada en el valor hash de la ventana. Esto también permite enviar enlaces a colegas, que ven "la misma" página. El truco consiste en cambiar el hash de la ubicación cuando se selecciona otra pestaña. Si ya usa # en su página, posiblemente la etiqueta hash deba dividirse. En mi aplicación, uso ":" como separador de valor 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, tiene que estar incrustado después de lo anterior en una <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
fuente
En la sección de secuencia de comandos, debe agregar un punto y coma al final de e.preventDefault();y$(this).tab('show');
Sean Adams-Hiett
12
Desafortunadamente, el navegador salta al contenido de la pestaña cuando hace clic en él. Este es el comportamiento predeterminado cuando establece el valor window.location.hash. Una alternativa podría ser usar push.state pero necesita un polyfill para IE <= 9. Para obtener más información y otras soluciones alternativas, visite stackoverflow.com/questions/3870057/…
Philipp Michael
3
¿Hay alguna forma de evitar el "desplazamiento falso" a la identificación en cuestión cuando hacemos clic en el elemento?
Patrice Poliquin
1
El desplazamiento se debe a la identificación asignada a las páginas de pestañas. Si utiliza ID semánticos y modifica el hash (es decir, agrega prefijo / sufijo), no se reconocerá como un ID válido y no se producirá ningún desplazamiento. Ampliará la respuesta con esto.
Alex Mazzariol
1
@koppor funciona, pero cuando salto directamente a la otra pestaña guardada (a través del enlace), muestra la pestaña de inicio o la primera pestaña rápidamente alrededor de 1 segundo antes de saltar a la pestaña del enlace. Cualquier idea para evitar que se muestre la primera. pestaña ya que no es necesaria?
mboy
135

Este es el mejor que probé:

$(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
fuente
20
Esta funciona mejor que la solución aceptada (con mejor quiero decir: copiar y pegar funciona: D)
Cyril Duchon-Doris
3
mejor copiar y pegar: P
Ghostff
1
Creo que cambiar el selector a "a[data-toggle=tab]"sería mejor. La forma en que está escrito el selector ahora también cambia la URL del navegador al hacer clic en un enlace para, por ejemplo, abrir un modal.
leifdenby
5
Es posible que desee agregar corchetes en el selector, como 'a [href = "' + location.hash + '"]'. Tropecé con un error de sintaxis.
asdacap
1
El uso de esto tal como está entra en conflicto con los menús desplegables de Bootstrap (qué uso data-toggle="dropdown"y cuál tengo en la misma página con pestañas en un caso. Como alguien sugirió aquí, simplemente reemplazar $(document.body).on("click", "a[data-toggle]", function(event) {con $(document.body).on("click", "a[data-toggle='tab']", function(event) {me
funcionó
44

Una mezcla entre otras respuestas:

  • Sin saltar al hacer clic
  • Guardar en hash de ubicación
  • Guardar en localStorage (por ejemplo: para enviar formulario)
  • Simplemente copie y pegue;)

    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');
    });
insign
fuente
1
Es una pena que probé las otras soluciones primero, ¡esta funciona mejor!
tdc
2
La mejor solución que he probado de muchos diferentes. El salto al contenido de la pestaña fue molesto
kentor
4
El salto de contenido sigue ahí con esta respuesta
shazyriver
2
Excelente solución: copiar, pegar, ir a almorzar. Agradable.
Gary Stanton
1
La mejor solución de todos los tiempos
afortunado
19

El código de Xavi estaba funcionando casi completamente. Pero al navegar a otra página, enviar un formulario y luego ser redirigido a la página con mis pestañas no estaba cargando la pestaña guardada en absoluto.

localStorage al rescate (cambió ligeramente el código 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
fuente
2
¡Esto es oro! ¡Funciona incluso con modales! Gran respuesta.
Lech Osiński
2
Este código es fantástico y funciona muy bien si desea que la pestaña permanezca seleccionada incluso si el usuario abandona el sitio (finaliza la sesión) y regresa más tarde. Para que la selección persista solo durante la sesión actual y vuelva a la pestaña predeterminada en la próxima sesión, reemplace las dos instancias de "localStorage" con "sessionStorage".
Gary.Ray
Solución de copiar / pegar breve y sencilla que funciona muy bien con Bootstrap 4.
Soporte de CFP
¡Guau tremenda solución!
Jilani A
1
[data-toggle="pill"]para pastillas
mxmissile
12

Este usa HTML5 localStoragepara almacenar la pestaña activa

$('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
fuente
esto es bueno, pero una desventaja es que no podría compartir enlaces con la pestaña activa
lfender6445
esto es bueno, la ventaja es que no presenta un problema en el que "window.location.hash" agrega valor hash al parámetro de solicitud http en la URL, lo que provoca una colisión y un parámetro incorrecto leído por otra solicitud http, como la paginación, etc.
Dung
4

Basándome en las respuestas proporcionadas por Xavi Martínez y koppor, se me ocurrió una solución que usa el hash de url o localStorage dependiendo de la disponibilidad de este ú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...
});

No se mantiene al día con el botón de retroceso como es el caso de la solución de Xavi Martínez .

Ziad
fuente
4

Mi código, funciona para mí, 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
fuente
4

Probé esto y funciona: (Reemplace esto con la píldora o pestaña que 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 ayude a alguien.

Aquí está el resultado: https://jsfiddle.net/neilbannet/ego1ncr5/5/

Neil Bannet
fuente
4

Bueno, esto ya es en 2018 pero creo que es mejor tarde que nunca (como un título en un programa de televisión), jejeje. Aquí abajo está el código jQuery que creo durante mi tesis.

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

y aquí está el código para las pestañas de arranque:

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


No olvide llamar al bootstrap y otras cosas fundamentales 

aquí hay códigos rápidos para ti:

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


Ahora vayamos a la explicación:

El código jQuery en el ejemplo anterior simplemente obtiene el valor del atributo href del elemento cuando se muestra una nueva pestaña usando el método jQuery .attr () y lo guarda localmente en el navegador del usuario a través del objeto HTML5 localStorage. Más tarde, cuando el usuario actualiza la página, recupera estos datos y activa la pestaña relacionada a través del método .tab ('mostrar').

¿Busca algunos ejemplos? aquí hay uno para ustedes ... https://jsfiddle.net/Wineson123/brseabdr/

Ojalá mi respuesta pudiera ayudarlos a todos .. ¡Cheerio! :)

Sr. Winson
fuente
2

Como aún no puedo comentar, copié la respuesta de arriba, realmente me ayudó. Pero lo cambié para que funcione con cookies en lugar de #id, así que quería compartir las alteraciones. Esto hace posible almacenar la pestaña activa durante más tiempo que solo una actualización (por ejemplo, redirección múltiple) o cuando la identificación ya se usa y no desea implementar el método de división de 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
fuente
Gracias por la actualización. En realidad, estaba buscando tal resolución, pero en el momento que quería, solo obtuve la respuesta de @koppor como trabajando una. De hecho, esa es una de las mejores formas de hacerlo si queremos usar la función de retroceso. Gracias por la actualización
Code Lover
2

Probé el código ofrecido por Xavi Martínez . Funcionó pero no para IE7. El problema es que las pestañas no hacen referencia a ningún contenido relevante.
Entonces, prefiero este código para resolver ese 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
fuente
esto es bueno, pero una desventaja es que no podría compartir enlaces con la pestaña activa
lfender6445
1

Gracias por compartir.

Al leer todas las soluciones. Se me ocurrió una solución que usa el hash url o localStorage dependiendo de la disponibilidad de este último con el siguiente código:

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

Para Bootstrap v4.3.1. Prueba a continuación:

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

Usando html5 cociné este:

En algún lugar de la página:

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

El viewbag solo debe contener la identificación de la página / elemento, por ejemplo: "prueba"

Creé un site.js y agregué el script en la página:

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

Ahora todo lo que tienes que hacer es agregar tu identificación a tu barra de navegación. P.ej.:

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

Todos saludan el atributo de datos :)

Theodor Alexander Hkansson Hei
fuente
0

Además de la respuesta de Xavi Martínez evitando el salto al clic

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

Pestañas anidadas

implementación con el carácter "_" 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
fuente
0

Usamos el disparador jquery para cargar y hacer que un script presione el botón para nosotros

$ (". class_name"). trigger ('hacer clic');

Dan Kaiser
fuente
0

Ay, hay tantas formas de hacer esto. Se me ocurrió esto, breve y simple. Espero que esto ayude a otros.

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

Hay una solución después de volver a cargar la página y mantener la pestaña esperada como seleccionada.

Supongamos que después de guardar los datos, la URL redirigida es: my_url # tab_2

Ahora, a través del siguiente script, la pestaña esperada permanecerá seleccionada.

$(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
fuente
La clase activa se asigna automáticamente a la etiqueta de anclaje, por lo que se elimina con $ ('. Nav-tabs a'). RemoveClass ('active'); este guión.
Hasib Kamal