简体   繁体   中英

How to stay on selected tab after refresh?

I have created tabs for my content instead of different HTML files, using anchor tags and fading them in and out with jQuery, but one problem I face is that if the user refreshes the page the home tab (initial tab) will be selected instead of the previously opened one.

I am currently using sessionStorage to store the previously opened tab like below:

$(document).ready(function() {

// Have the previously selected tab open
    if (sessionStorage.activeTab) {
        $('.tab-content ' + sessionStorage.activeTab).show().siblings().hide();
    //  ^ This one changes the tab to the previously opened, but after document has loaded :(
    }

// Enable, disable and switch tabs on click
$('.navbar .menu li a').on('click', function(e)  {
    var currentAttrValue = $(this).attr('href');

    // Show/Hide Tabs
    $('.tab-content ' + currentAttrValue).fadeIn(2000).siblings().hide();
    sessionStorage.activeTab = currentAttrValue;

    // Change/remove current tab to active
    $(this).parent('li').addClass('active').siblings().removeClass('active');
    $('.navbar .menu li a span').removeClass('active_span').removeClass('active_span2');
    $(this).children().addClass('active_span');
    e.preventDefault();
 });

In the lower part of my code above, I have these lines which make white the icon and the word (eg. () Parentheses) belonging to the current tab white to show that they are active:

$(this).parent('li').addClass('active').siblings().removeClass('active');
// ^ Icon

$(this).children().addClass('active_span');
// ^ Word

I tried to set them as items in sessionStorage too, as so:

sessionStorage.activeIcon = $(this).parent('li');
sessionStorage.activeWord = $(this).children();

but when I called them in the:

if (sessionStorage.activeTab) {}

it returned 'Null'. How can I save the icon and the word belonging to the previously opened tab and make them white as well as load all of them along with the tab before the document is loaded, so that no visible result of the changed is seen by the user?

It doesn't necessarily have to use sessionStorage. Any working answer or any answer that will put me on the right track is gladly accepted.

I am looking forward to reading your answers :)

PS: I'm not using jQuery UI tabs or any other third party plugin.

[EDIT]

HTML (Tab-links):

<div class = "navbar tabs">
    <ul class = "menu tab-links">
        <li class = "active"><a class = "links" href = "#Dashboard"><span class = "focus active_span"><i class="fa fa-home fa-fw" aria-hidden = "true"></i><span class = "hider active_span">&nbsp;Dashboard</span></span></a></li>
        <li><a class = "links" href = "#Analytics"><span class = "focus"><i class = "fa fa-bar-chart fa-fw" aria-hidden = "true"></i><span class = "hider">&nbsp;Analytics</span></span></a></li>
        <li><a class = "links" href = "#Affiliate"><span class = "focus"><i class = "fa fa-user-plus fa-fw" aria-hidden = "true"></i><span class = "hider">&nbsp;Affiliate</span></span></a></li>
        <li><a class = "links" href = "#CashOut"><span class = "focus"><i class = "fa fa-money fa-fw" aria-hidden = "true"></i><span class = "hider">&nbsp;Cash Out</span></span></a></li>
        <li><a class = "links" href = "#Contest"><span class = "focus"><i class = "fa fa-trophy fa-fw" aria-hidden = "true"></i><span class = "hider">&nbsp;Contest</span></span></a></li>
        <li><a class = "links" href = "#Game"><span class = "focus"><i class="fa fa-gamepad fa-fw" aria-hidden = "true"></i><span class = "hider">&nbsp;Game</span></span></a></li>
        <li><a class = "links" href = "#FAQ"><span class = "focus"><i class = "fa fa-question-circle fa-fw" aria-hidden = "true"></i><span class = "hider">&nbsp;FAQ</span></span></a></li>
        <li><a class = "links" href = "#Settings"><span class = "focus"><i class = "fa fa-cog fa-fw" aria-hidden = "true"></i><span class = "hider">&nbsp;Settings</span></span></a></li>
    </ul>
</div>

HTML (Tab-content):

<div class = "tab-content">
    <div id = "Dashboard" class = "active tab"></div>
    <div id = "Analytics" class = "tab"></div>
    <div id = "Affiliate" class = "tab"></div>
    <div id = "FAQ" class = "tab"></div>
    <div id = "Settings" class = "tab"></div>
</div>

[SOLVED]

JavaScript:

To make the code work, we have to replace:

// Have the previously selected tab open
    if (sessionStorage.activeTab) {
        $('.tab-content ' + sessionStorage.activeTab).show().siblings().hide();
    //  ^ This one changes the tab to the previously opened, but after document has loaded :(
    }

with:

var activeTab = sessionStorage.activeTab;
$(".tab-content").fadeIn(1000);
if (activeTab) {
    $('.tab-content ' + activeTab ).show().siblings().hide();
    // also make sure you your active class to the corresponding tab menu here
    $(".menu li a[href=" + "\"" + activeTab + "\"" + "]").parent().addClass('active').siblings().removeClass('active');
    $(".menu li a[href=" + "\"" + activeTab + "\"" + "]").children('span').addClass("active_span").parent().parent().siblings().children().children().removeClass('active_span');
    $(".menu li a[href=" + "\"" + activeTab + "\"" + "]").children('span').children().addClass("active_span").parent().parent().parent().siblings().children().children().children().removeClass('active_span');
}
else {
    activeTab = "#Dashboard";
    $('.tab-content ' + activeTab ).show().siblings().hide();
    // also make sure you your active class to the corresponding tab menu here
    $(".menu li a[href=" + "\"" + activeTab + "\"" + "]").parent().addClass('active').siblings().removeClass('active');
    $(".menu li a[href=" + "\"" + activeTab + "\"" + "]").children('span').addClass("active_span").parent().parent().siblings().children().children().removeClass('active_span');
    $(".menu li a[href=" + "\"" + activeTab + "\"" + "]").children('span').children().addClass("active_span").parent().parent().parent().siblings().children().children().children().removeClass('active_span');
}

HTML:

In the HTML, we have to remove the classes 'active' and 'active_span' from the default <li> and <a> respectively.

<li class = "active"><a class = "links" href = "#Dashboard"><span class = "focus active_span"><i class="fa fa-home fa-fw" aria-hidden = "true"></i><span class = "hider active_span">&nbsp;Dashboard</span></span></a></li>

CSS:

Finally, in CSS we have to set the tab-content:

display: none;

Thanks to @KishoreBarik and @DavidChelliah for their tremendous help.

Most of the tab based solutions prefer hash value in the URL to deep link their content. The hash value from the URL will be set in URL, like below

Www.xyz.com/test#tab1

tab1 is the ID of the tabbed content div and this also semantically reveals a correct meaning that, tab1 is a content internal document heading/link that should be in focus. Even if page reloads, the browser will tend to automatically scroll down to that particular content section.

From the implementation point of view, On pageload just read through your tab anchor links and compare it against the hash value in the URL. If it matches, highlight the particular tab. This kind of offloads the requirement from your part to persist the last clicked link.

  $(function() {
    var hash = window.location.hash;
    var selectedTab = $('.navbar .menu li a [href= "'+hash+'"]');
    if(selectedTab.length){
         //Do your particular tab toggling
     }
});

If you are using hash mechanism, inside your document ready function replace your code

if (sessionStorage.activeTab) {
        $('.tab-content ' + sessionStorage.activeTab).show().siblings().hide();

with code to show the active tab as per hash like

var activeTab = window.location.hash;
if(activeTab.length){
  $('.tab-content ' + activeTab ).show().siblings().hide();
  // also make sure you set your active class to the corresponding tab menu here
}

sessionStorage should be used with .setItem() and .getItem() function.

Storage can only store data in string form, so when you need store object, you should use JSON.stringify() to change it to string, and JSON.parse() before you use it. So you can store the activeTab, word and icon in one object.

I suggest you store the icon by its class, jQuery object can't be used after JSON stringify and parse. The same with word.

There is no need to change the tab before document.ready, just add display: none; to body, and make it visible after you change the tab.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM