Wie halte ich den aktuellen Tab mit Twitter-Bootstrap nach einem erneuten Laden der Seite aktiv?


86

Ich verwende derzeit Registerkarten mit Twitter Bootstrap und möchte dieselbe Registerkarte auswählen, nachdem ein Benutzer Daten gepostet und die Seite neu geladen hat.

Wie wird das gemacht?

Mein aktueller Aufruf, die Registerkarten zu öffnen, sieht folgendermaßen aus:

<script type="text/javascript">

$(document).ready(function() {

    $('#profileTabs a:first').tab('show');
});
</script>

Meine Tabs:

<ul id="profileTabs" class="nav nav-tabs">
    <li class="active"><a href="#profile" data-toggle="tab">Profile</a></li>
    <li><a href="#about" data-toggle="tab">About Me</a></li>
    <li><a href="#match" data-toggle="tab">My Match</a></li>
</ul>

1
Dies scheint eine doppelte Frage an stackoverflow.com/questions/18999501/…
koppor

Antworten:


137

Sie müssen localStorage oder Cookies verwenden, um dies zu verwalten. Hier ist eine schnelle und schmutzige Lösung, die erheblich verbessert werden kann, aber möglicherweise einen Ausgangspunkt bietet:

$(function() { 
    // for bootstrap 3 use 'shown.bs.tab', for bootstrap 2 use '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('lastTab', $(this).attr('href'));
    });

    // go to the latest tab, if it exists:
    var lastTab = localStorage.getItem('lastTab');
    if (lastTab) {
        $('[href="' + lastTab + '"]').tab('show');
    }
});

Schöne Knospe, Ihre Lösung könnte in Joomla 30 Core, joomlacode.org/gf/project/joomla/tracker/…
Benn

12
Bessere Verwendung $(this).attr('href')statt der $(e.target).attr('id')gibt Ihnen den Hash ohne die vollständige URL. Sie müssen auch das .tab()auf das a-Tag mit data-toggle="tab"anstelle von anwenden $('#'+lastTab). Siehe auch: stackoverflow.com/questions/16808205/…
Bass Jobsen

3
Es sieht so aus, als ob sich die Methode in Bootstrap 3 geringfügig ändert. Sie shownscheint nicht mehr zu funktionieren und musste geändert werden shown.bs.tab. Hinweis: Ich verstehe Javascript et al. Ebenso gut wie Wirtschaftswissenschaften. Wenn Sie also wissen, was los ist, können Sie mich gerne korrigieren.
Chaz

10
Geändert, um mit mehreren Registerkarten-Steuerelementen (und Bootstrap 3) zu arbeiten: gist.github.com/brendanmckenzie/8f8008d3d51c07b2700f
Brendan

1
Es geht zur ersten Registerkarte und
kehrt

23

Damit funktioniert dies mithilfe von Cookies und das Entfernen der 'aktiven' Klasse aus allen anderen Registerkarten und Registerkartenfenstern ... und das Hinzufügen der 'aktiven' Klasse zum aktuellen Registerkarten- und Registerkartenbereich.

Ich bin sicher, es gibt einen besseren Weg, dies zu tun, aber dies scheint in diesem Fall zu funktionieren.

Benötigt das jQuery-Cookie-Plugin.

$(function() { 
  $('a[data-toggle="tab"]').on('shown', function(e){
    //save the latest tab using a cookie:
    $.cookie('last_tab', $(e.target).attr('href'));
  });

  //activate latest tab, if it exists:
  var lastTab = $.cookie('last_tab');
  if (lastTab) {
      $('ul.nav-tabs').children().removeClass('active');
      $('a[href='+ lastTab +']').parents('li:first').addClass('active');
      $('div.tab-content').children().removeClass('active');
      $(lastTab).addClass('active');
  }
});

Ich konnte die localStorage-Lösung nicht zum Laufen bringen, obwohl dies logisch schien. Diese sofort einsatzbereite Lösung und das $ .cookie-Plugin sind SEHR praktisch.
Michael J. Calkins

Wenden Sie .tab () auf ein Tag mit data-toggle = "tab" an, anstatt Klassen zu entfernen und hinzuzufügen. Siehe auch: stackoverflow.com/questions/16808205/…
Bass Jobsen

Für mein Layout musste ich, da ich für die Divs 'Einblenden aktiv' verwendet habe, die letzten beiden Zeilen ändern, um 'in aktiv' hinzuzufügen oder zu entfernen.
Obromios

18

Alle anderen Antworten sind richtig. Diese Antwort berücksichtigt die Tatsache, dass man mehrere ul.nav.nav-pillsoder haben könnteul.nav.nav-tabs dieselbe Seite hat. In diesem Fall schlagen die vorherigen Antworten fehl.

localStorageWird immer noch verwendet, jedoch mit einem String JSONals Wert. Hier ist der Code:

$(function() {
  var json, tabsState;
  $('a[data-toggle="pill"], a[data-toggle="tab"]').on('shown', function(e) {
    var href, json, parentId, tabsState;

    tabsState = localStorage.getItem("tabs-state");
    json = JSON.parse(tabsState || "{}");
    parentId = $(e.target).parents("ul.nav.nav-pills, ul.nav.nav-tabs").attr("id");
    href = $(e.target).attr('href');
    json[parentId] = href;

    return localStorage.setItem("tabs-state", JSON.stringify(json));
  });

  tabsState = localStorage.getItem("tabs-state");
  json = JSON.parse(tabsState || "{}");

  $.each(json, function(containerId, href) {
    return $("#" + containerId + " a[href=" + href + "]").tab('show');
  });

  $("ul.nav.nav-pills, ul.nav.nav-tabs").each(function() {
    var $this = $(this);
    if (!json[$this.attr("id")]) {
      return $this.find("a[data-toggle=tab]:first, a[data-toggle=pill]:first").tab("show");
    }
  });
});

Dieses Bit kann für die gesamte App auf allen Seiten verwendet werden und funktioniert sowohl für Registerkarten als auch für Pillen. Auch stellen Sie sicher , die Laschen oder Pillen sind nicht standardmäßig aktiv , sonst werden Sie einen Flicker - Effekt auf Laden der Seite sehen.

Wichtig : Stellen Sie sicher, dass der Elternteil uleine ID hat. Danke Alain


2
Ersetzen Sie für BS3 außerdem das Ereignis "angezeigt" durch "angezeigt.bs.tab"
Alain

18

Verwenden Sie für die beste Option diese Technik:

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

  //go to the latest tab, if it exists:
  var lastTab = localStorage.getItem('lastTab');

  if (lastTab) {
    $('a[href="'+lastTab+'"]').click();
  }
});

12

Ich bevorzuge es, die ausgewählte Registerkarte im Hashwert des Fensters zu speichern. Dies ermöglicht auch das Senden von Links an Kollegen, die dann "dieselbe" Seite sehen. Der Trick besteht darin, den Hash der Position zu ändern, wenn eine andere Registerkarte ausgewählt wird. Wenn Sie auf Ihrer Seite bereits # verwenden, muss möglicherweise das Hash-Tag aufgeteilt werden. In meiner App verwende ich ":" als Hashwerttrennzeichen.

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

Vielen Dank für diese Antwort. Es funktioniert gut für mich und ich wollte mich nicht nur für dieses Problem mit Cookies befassen, also ist es großartig.
Nico008

@koppor, das funktioniert nicht da es ein Postback Event gibt. Ich habe den Linkbutton hinzugefügt. Nachdem ich <asp:LinkButton CssClass="form-search" ID="LinkButtonSearch" runat="server">Search</asp:LinkButton> auf die Schaltfläche geklickt habe, ist es die Standardregisterkarte, die aktiv wird, nicht die aktuelle Registerkarte. Wie kann ich das beheben?
Djama

6

Um zu verhindern, dass die Seite auf der ersten Registerkarte und dann auf der Registerkarte, die vom Cookie gespeichert wurde, blinkt (dies tritt auf, wenn Sie die Klasse "aktiv" standardmäßig in der ersten Registerkarte festlegen).

Entfernen Sie die Klasse "aktiv" von Registerkarten und Fenstern wie:

<ul class="nav nav-tabs">
<div id="p1" class="tab-pane">

Fügen Sie das folgende Skript ein, um die erste Registerkarte als Standard festzulegen (Erfordert das jQuery-Cookie-Plugin).

    $(function() { 
        $('a[data-toggle="tab"]').on('shown', function(e){
            //save the latest tab using a cookie:
            $.cookie('last_tab', $(e.target).attr('href'));
        });
        //activate latest tab, if it exists:
        var lastTab = $.cookie('last_tab');
        if (lastTab) {
            $('a[href=' + lastTab + ']').tab('show');
        }
        else
        {
            // Set the first tab if cookie do not exist
            $('a[data-toggle="tab"]:first').tab('show');
        }
    });

3

Willst du einen Fading-Effekt? Aktualisierte Version von @ Oktavs Code:

  1. Für Bootstrap 3
  2. Richtet die Klassen auf dem div von li und tab ein, damit das Fading ordnungsgemäß funktioniert. Beachten Sie, dass alle Inhaltsbereiche benötigt werdenclass="tab-pane fade"

Code:

// See http://stackoverflow.com/a/16984739/64904
// Updated by Larry to setup for fading
$(function() {
  var json, tabsState;
  $('a[data-toggle="pill"], a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
    var href, json, parentId, tabsState;
    tabsState = localStorage.getItem("tabs-state");
    json = JSON.parse(tabsState || "{}");
    parentId = $(e.target).parents("ul.nav.nav-pills, ul.nav.nav-tabs").attr("id");
    href = $(e.target).attr('href');
    json[parentId] = href;
    return localStorage.setItem("tabs-state", JSON.stringify(json));
  });
  tabsState = localStorage.getItem("tabs-state");
  json = JSON.parse(tabsState || "{}");
  $.each(json, function(containerId, href) {
    var a_el = $("#" + containerId + " a[href=" + href + "]");
    $(a_el).parent().addClass("active");
    $(href).addClass("active in");
    return $(a_el).tab('show');
  });
  $("ul.nav.nav-pills, ul.nav.nav-tabs").each(function() {
    var $this = $(this);
    if (!json[$this.attr("id")]) {
      var a_el = $this.find("a[data-toggle=tab]:first, a[data-toggle=pill]:first"),
          href = $(a_el).attr('href');
      $(a_el).parent().addClass("active");
      $(href).addClass("active in");
      return $(a_el).tab("show");
    }
  });
});

3

Ich hatte Registerkarten auf mehreren Seiten und localStorage behält lastTab auch von vorherigen Seiten bei. Da also lastTab der vorherigen Seite gespeichert war, wurde hier keine passende Registerkarte gefunden, sodass nichts angezeigt wurde. Ich habe es so modifiziert.

$(document).ready(function(){
    //console.log($('a[data-toggle="tab"]:first').tab('show'))
    $('a[data-toggle="tab"]').on('shown.bs.tab', function () {
        //save the latest tab; use cookies if you like 'em better:
        localStorage.setItem('lastTab', $(this).attr('href'));
    });

    //go to the latest tab, if it exists:
    var lastTab = localStorage.getItem('lastTab');
    if ($('a[href=' + lastTab + ']').length > 0) {
        $('a[href=' + lastTab + ']').tab('show');
    }
    else
    {
        // Set the first tab if cookie do not exist
        $('a[data-toggle="tab"]:first').tab('show');
    }
})

edit: Mir ist aufgefallen, dass ich lastTabfür verschiedene Seiten unterschiedliche Variablennamen haben muss , sonst überschreiben sie sich immer gegenseitig. zB lastTab_klanten, lastTab_bestellingenusw. für zwei unterschiedliche Seiten klantenund die bestellingenbeide in tabs angezeigten Daten.

$(document).ready(function(){
    //console.log($('a[data-toggle="tab"]:first').tab('show'))
    $('a[data-toggle="tab"]').on('shown.bs.tab', function () {
        //save the latest tab; use cookies if you like 'em better:
        localStorage.setItem('lastTab_klanten', $(this).attr('href'));
    });

    //go to the latest tab, if it exists:
    var lastTab_klanten = localStorage.getItem('lastTab_klanten');
    if (lastTab_klanten) {
        $('a[href=' + lastTab_klanten + ']').tab('show');
    }
    else
    {
        // Set the first tab if cookie do not exist
        $('a[data-toggle="tab"]:first').tab('show');
    }
})

3

Ich habe dafür gesorgt, dass es mit einer ähnlichen Lösung wie @dgabriel funktioniert. In diesem Fall werden die Links <a>nicht benötigt id. Es wird die aktuelle Registerkarte anhand der Position identifiziert.

$(function() { 
  $('a[data-toggle="tab"]').on('shown', function (e) {
    var indexTab = $('a[data-toggle="tab"]').index($(this)); // this: current tab anchor
    localStorage.setItem('lastVisitedTabIndex', indexTab);
  });

  //go to the latest tab, if it exists:
  var lastIndexTab  = localStorage.getItem('lastVisitedTabIndex');
  if (lastIndexTab) {
      $('a[data-toggle="tab"]:eq(' + lastIndexTab + ')').tab('show');
  }
});

Ich denke, Ihr Code ist falsch herum, um getItem sollte vorher gezeigt werden, löst auch das Problem der zweimaligen Deklaration von indexTab.
John Magnolia

@ JohnMagnolia Ich habe das indexTabzweimal benannt, ist aber ein Unterschied. Index. Also werde ich den 2. anrufen lastIndexTab. In Bezug auf shownist dies ein Ereignis, das erst ausgelöst wird, wenn Sie einen Tab öffnen. Es spielt also keine Rolle, ob es vorher ist getItem.
Jaider

1

Ich schlage folgende Änderungen vor

  1. Verwenden Sie ein Plugin wie amplify.store , das eine Crossbrowser / Crossplatform Localstorage-API mit integrierten Fallbacks bereitstellt.

  2. Richten Sie die Registerkarte, die gespeichert werden soll, wie $('#div a[data-toggle="tab"]')folgt aus, um diese Funktionalität auf mehrere Registerkartencontainer zu erweitern, die auf derselben Seite vorhanden sind.

  3. Verwenden Sie eine eindeutige Kennung (url ??), um die zuletzt verwendeten Registerkarten auf mehreren Seiten zu speichern und wiederherzustellen.


$(function() { 
  $('#div a[data-toggle="tab"]').on('shown', function (e) {
    amplify.store(window.location.hostname+'last_used_tab', $(this).attr('href'));
  });

  var lastTab = amplify.store(window.location.hostname+'last_used_tab');
  if (lastTab) {
    $("#div a[href="+ lastTab +"]").tab('show');
  }
});

1

Einfache Lösung ohne lokalen Speicher:

$(".nav-tabs a").on("click", function() {
    location.hash = $(this).attr("href");
});

0

Serverseitiger Ansatz. Stellen Sie sicher, dass alle HTML-Elemente class = "" haben, falls nichts angegeben ist. Andernfalls müssen Sie mit Nullen umgehen.

    private void ActiveTab(HtmlGenericControl activeContent, HtmlGenericControl activeTabStrip)
    {
        if (activeContent != null && activeTabStrip != null)
        {
            // Remove active from content
            Content1.Attributes["class"] = Content1.Attributes["class"].Replace("active", "");
            Content2.Attributes["class"] = Content2.Attributes["class"].Replace("active", "");
            Content3.Attributes["class"] = Content3.Attributes["class"].Replace("active", "");

            // Remove active from tab strip
            tabStrip1.Attributes["class"] = tabStrip1.Attributes["class"].Replace("active", "");
            tabStrip2.Attributes["class"] = tabStrip2.Attributes["class"].Replace("active", "");
            tabStrip3.Attributes["class"] = tabStrip3.Attributes["class"].Replace("active", "");

            // Set only active
            activeContent.Attributes["class"] = activeContent.Attributes["class"] + " active";
            activeTabStrip.Attributes["class"] = activeTabStrip.Attributes["class"] + " active";
        }
    }

0

Wenn Sie die erste Registerkarte beim ersten Aufrufen der Seite anzeigen möchten, verwenden Sie diesen Code:

    <script type="text/javascript">
        function invokeMeMaster() {
        var chkPostBack = '<%= Page.IsPostBack ? "true" : "false" %>';
            if (chkPostBack == 'false') {
                $(function () {
                    // for bootstrap 3 use 'shown.bs.tab', for bootstrap 2 use '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('lastTab', $(this).attr('href'));
                    });

                });
            }
            else {
                $(function () {

                    // for bootstrap 3 use 'shown.bs.tab', for bootstrap 2 use '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('lastTab', $(this).attr('href'));
                    });

                    // go to the latest tab, if it exists:
                    var lastTab = localStorage.getItem('lastTab');
                    if (lastTab) {
                        $('[href="' + lastTab + '"]').tab('show');
                    }

                });

            }
        }
        window.onload = function() { invokeMeMaster(); };

    </script>


0

Hier ist ein Ausschnitt, den ich erstellt habe und der mit Bootstrap 3 und jQuery sowie mit verschiedenen URLs mit unterschiedlichen Registerkarten funktioniert . Es werden zwar nicht mehrere Registerkarten pro Seite unterstützt , es sollte jedoch eine einfache Änderung sein, wenn Sie diese Funktion benötigen.

/**
 * Handles 'Bootstrap' package.
 *
 * @namespace bootstrap_
 */

/**
 * @var {String}
 */
var bootstrap_uri_to_tab_key = 'bootstrap_uri_to_tab';

/**
 * @return {String}
 */
function bootstrap_get_uri()
{
    return window.location.href;
}

/**
 * @return {Object}
 */
function bootstrap_load_tab_data()
{
    var uriToTab = localStorage.getItem(bootstrap_uri_to_tab_key);
    if (uriToTab) {
    try {
        uriToTab = JSON.parse(uriToTab);
        if (typeof uriToTab != 'object') {
        uriToTab = {};
        }
    } catch (err) {
        uriToTab = {};
    }
    } else {
    uriToTab = {};
    }
    return uriToTab;
}

/**
 * @param {Object} data
 */
function bootstrap_save_tab_data(data)
{
    localStorage.setItem(bootstrap_uri_to_tab_key, JSON.stringify(data));
}

/**
 * @param {String} href
 */
function bootstrap_save_tab(href)
{
    var uri = bootstrap_get_uri();
    var uriToTab = bootstrap_load_tab_data();
    uriToTab[uri] = href;
    bootstrap_save_tab_data(uriToTab);
}

/**
 *
 */
function bootstrap_restore_tab()
{
    var uri = bootstrap_get_uri();
    var uriToTab = bootstrap_load_tab_data();
    if (uriToTab.hasOwnProperty(uri) &&
    $('[href="' + uriToTab[uri] + '"]').length) {
    } else {
    uriToTab[uri] = $('a[data-toggle="tab"]:first').attr('href');
    }
    if (uriToTab[uri]) {
        $('[href="' + uriToTab[uri] + '"]').tab('show');
    }
}

$(document).ready(function() {

    if ($('.nav-tabs').length) {

    // for bootstrap 3 use 'shown.bs.tab', for bootstrap 2 use 'shown' in the next line
    $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
        bootstrap_save_tab($(this).attr('href'));
    });
    bootstrap_restore_tab();

    }

});

0

$ (Dokument) .ready (Funktion () {

        if (JSON.parse(localStorage.getItem('currentClass')) == "active")
        {
            jQuery('#supporttbl').addClass('active')
            $('.sub-menu').css({ "display": "block" });
        }

        $("#supporttbl").click(function () { 
            var currentClass;
            if ($(this).attr('class')== "active") { 

                currentClass = $(this).attr('class');

                localStorage.setItem('currentClass', JSON.stringify(currentClass));
                console.log(JSON.parse(localStorage.getItem('currentClass')));

                jQuery('#supporttbl').addClass('active')
                $('.sub-menu').css({ "display": "block" });

            } else {

                currentClass = "Null"; 

                localStorage.setItem('currentClass', JSON.stringify(currentClass));
                console.log(JSON.parse(localStorage.getItem('currentClass')));

                jQuery('#supporttbl').removeClass('active')
                $('.sub-menu').css({ "display": "none" });

            }  
        });

});


0

Wenn Sie mehr als eine Registerkarte auf der Seite haben, können Sie den folgenden Code verwenden

<script type="text/javascript">
$(document).ready(function(){
    $('#profileTabs').on('show.bs.tab', function(e) {
        localStorage.setItem('profileactiveTab', $(e.target).attr('href'));
    });
    var profileactiveTab = localStorage.getItem('profileactiveTab');
    if(profileactiveTab){
        $('#profileTabs a[href="' + profileactiveTab + '"]').tab('show');        
    }
    $('#charts-tab').on('show.bs.tab', function(e) {
        localStorage.setItem('chartsactiveTab', $(e.target).attr('href'));
    });
    var chartsactiveTab = localStorage.getItem('chartsactiveTab');
    if(chartsactiveTab){
        $('#charts-tab a[href="' + chartsactiveTab + '"]').tab('show');        
    }     
});
</script>

0

Dadurch werden die Registerkarten aktualisiert, jedoch erst, nachdem alles im Controller geladen wurde.

// >= angular 1.6 angular.element(function () {
angular.element(document).ready(function () {
    //Here your view content is fully loaded !!
    $('li[href="' + location.hash + '"] a').tab('show');
});

0

Ich benutze dies mit MVC:

  • Das Modell enthält ein Ganzzahlfeld SelectedTab, über das der Wert an die POST-Methode gesendet werden kann

JavaScript-Bereich:

<script type="text/javascript">
    $(document).ready(function () {
       var index = $("input#SelectedTab").val();
       $("#tabstrip > ul li:eq(" + index + ")").addClass("k-state-active");

       $("#tabstrip").kendoTabStrip();
    });
    function setTab(index) {
      $("input#SelectedTab").val(index)
    }
</script>

HTML-Bereich:

@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.HiddenFor(model => model.SelectedTab)
<div id="tabstrip">
    <ul>
        <li onclick="setTab(0)">Content 0</li>
        <li onclick="setTab(1)">Content 1</li>
        <li onclick="setTab(2)">Content 2</li>
        <li onclick="setTab(3)">Content 3</li>
        <li onclick="setTab(4)">Content 4</li>
    </ul>
    <div>

    </div>
    <div>

    </div>
    <div>

    </div>
    <div>

    </div>
    <div>

    </div>
</div>
<div class="content">
    <button type="submit" name="save" class="btn bg-blue">Save</button>
</div>
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.