CSS Tab, Switch on Page Load based on URL fragment (#hashtag)

PRRcomputers
PRRcomputers used Ask the Experts™
on
I've got some CSS tabs which are switching via Javascript when clicked. That part is working just fine.  Now, I'd like to have someone land on the page and be taken to a particular tab if they have the appropriate #fragment at the end of their URL.  For example, if they visit www.example.com/index.html they will get the first (default) tab, but if they visit www.example.com/index.html#tab2 they'll get Tab 2.  That kind of thing.

Tabs are switching beautifully on click, now I just need to tweak this to get the page to activate a particular tab when a particular #hashtag (like above) is used.  I feel like I've done this before, but I'm totally drawing a blank on how.

HTML - the clickable tab headers
<ul class="tabs">
     <li class="active"><a href="#tab1">Tab 1</a></li>
     <li><a href="#tab2">Tab 2</a></li>
     <li><a href="#tab3">Tab 3</a></li>
     <li><a href="#tab4">Tab 4</a></li>
</ul>

Open in new window


HTML - the tabs themselves
<div class="tab_container">
     <div id="tab1" class="tab_content">
          ... stuff ...
     </div>
     etc. etc.

Open in new window


tabs.js
$(document).ready(function() {
&#9;
&#9;//When page loads...
&#9;$(".tab_content").hide(); //Hide all content
&#9;$("ul.tabs li:first").addClass("active").show(); //Activate first tab
&#9;$(".tab_content:first").show(); //Show first tab content

&#9;//On Click Event
&#9;$("ul.tabs li").click(function() {
&#9;
&#9;&#9;$("ul.tabs li").removeClass("active"); //Remove any "active" class
&#9;&#9;$(this).addClass("active"); //Add "active" class to selected tab
&#9;&#9;$(".tab_content").hide(); //Hide all tab content
&#9;
&#9;&#9;var activeTab = $(this).find("a").attr("href"); //Find the href attribute value to identify the active tab + content
&#9;&#9;$(activeTab).fadeIn(); //Fade in the active ID content
&#9;&#9;return false;
&#9;});
&#9;
&#9;});

Open in new window


Can I modify the "When page loads..." section of the Javascript so it activates "tab2" if someone arrives on this page with #tab2 on the end of their URL?  If so, how?
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Jon NormanInformation Systems Manager
Top Expert 2012

Commented:
This looks like jQuery so should be in the jQuery topic.


The solution should be:

$(document).ready(function() {
	
	//When page loads...
	$(".tab_content").hide(); //Hide all content
	$("ul.tabs li:first").addClass("active").show(); //Activate first tab
	$(".tab_content:first").show(); //Show first tab content

	//On Click Event
	$("ul.tabs li").click(function() {
	
		$("ul.tabs li").removeClass("active"); //Remove any "active" class
		$(this).addClass("active"); //Add "active" class to selected tab
		$(".tab_content").hide(); //Hide all tab content
	
		var activeTab = $(this).find("a").attr("href"); //Find the href attribute value to identify the active tab + content
		$(activeTab).fadeIn(); //Fade in the active ID content
		return false;
	});
        $("a[href=\""+location.hash+"\"").parent("ul.tabs li").click();
});

Open in new window

Author

Commented:
Thanks for the response, but that doesn't seem to work.  With that code in place, visiting www.example.com/index.html#tab2 still doesn't open the page with "tab2" active / out front.

I'm still learning JQuery - what was that additional line intended to do?  Is it supposed to simulate a click on a tab based on the hash in the URL?
Jon NormanInformation Systems Manager
Top Expert 2012
Commented:
Hi,

yes, that was supposed to click the li, that was a bad way of doing it anyway as it would have been loaded on tab1, then tab2 would have faded in.

the following definitely works - i've tested it this time:


<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<style>
.active,.active>a{color:red}
</style>
<script>
$(document).ready(function() {
    $(".tab_content").hide(); //hide all content
    var found = false;
    $("ul.tabs li").click(function() { //onclick events
        $("ul.tabs li").removeClass("active"); //Remove any "active" class
        $(this).addClass("active"); //Add "active" class to selected tab
        $(".tab_content").hide(); //Hide all tab content
        var activeTab = $(this).find("a").attr("href"); //Find the href attribute value to identify the active tab + content
        $(activeTab).fadeIn(); //Fade in the active ID content
        return false;
    }).each(function() {
        if ($(this).find("a").attr("href") == location.hash) {
            $(this).addClass("active").show();
            $($(this).find("a").attr("href")).show($(this).find("a").attr("href"));
            found = true;
        }
    });
    if (!found) {
        $("ul.tabs li:first").addClass("active").show(); //Activate first tab
        $(".tab_content:first").show(); //Show first tab content
    }
});
</script>
</head>
<body>
<div class="tab_container">      
    <div id="tab1" class="tab_content">... stuff 1...</div>
    <div id="tab2" class="tab_content">... stuff 2...</div>
    <div id="tab3" class="tab_content">... stuff 3...</div>
    <div id="tab4" class="tab_content">... stuff 4...</div>
</div>                                 
<ul class="tabs">
     <li><a href="#tab1">Tab 1</a></li>
     <li><a href="#tab2">Tab 2</a></li>
     <li><a href="#tab3">Tab 3</a></li>
     <li><a href="#tab4">Tab 4</a></li>
</ul>
</body>
</html>

Open in new window

Information Systems Manager
Top Expert 2012
Commented:
oh and I guess why it didn't work before was that the # in the selector needed to be escaped, and I had missed the end bracket as follows:
$("a[href=\"\\"+location.hash+"\"]").parent("ul.tabs li").click();

the following code also works, without the overhead of running another function (the each() function) against each of the list items:

$(document).ready(function() {
    $(".tab_content").hide();
    $("ul.tabs li").click(function() { //onclick events
        $("ul.tabs li").removeClass("active"); //Remove any "active" class
        $(this).addClass("active"); //Add "active" class to selected tab
        $(".tab_content").hide(); //Hide all tab content
        var activeTab = $(this).find("a").attr("href"); //Find the href attribute value to identify the active tab + content
        $(activeTab).fadeIn(); //Fade in the active ID content
        return false;
    });
    if ($("ul.tabs li a[href=\"\\"+location.hash+"\"]")) {
        $("a[href=\"\\"+location.hash+"\"]").parent("ul.tabs li").addClass("active").show();
        $(location.hash).show();
    }else{
        $("ul.tabs li:first").addClass("active").show(); //Activate first tab
        $(".tab_content:first").show(); //Show first tab content
    }
});

Open in new window

Author

Commented:
Exactly what I needed, thank you Jon.  The only modification I made to your lower overhead solution was I added one more .removeClass("active") to darken the first tab when another is selected by hash.  It all works brilliantly, thank you so much!

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial