History & Back Button Support using jQuery: Tabs

History & Back Button Support using jQuery Featuring Ben Alman's (@cowboy) jQuery BBQ Plugin

by bizamajig

HTML

<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.0/themes/humanity/jquery-ui.css">
<script src="http://github.com/cowboy/jquery-bbq/raw/v1.2.1/jquery.ba-bbq.js"></script>
<script src="http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js"></script>
<div class="tabs">
    <ul>
        <li class="tab"><a href="#div1">Tab 1</a></li>
        <li class="tab"><a href="#div2">Tab 2</a></li>
        <li class="tab"><a href="#div3">Tab 3</a></li>
    </ul>
    <div id="div1" class="content">Div 1</div>
    <div id="div2" class="content">Div 2</div>
    <div id="div3" class="content">Div 3</div>
</div>
<script type="text/javascript">
    firebug.env.height = 200;
</script>

CSS

.tabs ul {
    height: 36px;
    padding: 20px 20px 0 30px;
    width: 100%;
    margin: 0 auto;
    position: relative;
    overflow: hidden;
}

.tabs ul li {
    -webkit-border-top-left-radius: 10px;
    -webkit-border-top-right-radius: 10px;
    -webkit-border-bottom-right-radius: 0px;
    -webkit-border-bottom-left-radius: 0px;
    -moz-border-radius-topleft: 10px;
    -moz-border-radius-topright: 10px;
    -moz-border-radius-bottomright: 0px;
    -moz-border-radius-bottomleft: 0px;
    border-top-left-radius: 10px;
    border-top-right-radius: 10px;
    border-bottom-right-radius: 0px;
    border-bottom-left-radius: 0px;
    float: left;
    width: 100px;
    margin: 0 10px 0 0;
    background-color: #cccccc;
    border: solid 1px #000000;
    position: relative;
    z-index: 1;
}

.tabs ui li.active {
    z-index: 3;
}

.tabs ul li a:link, .tabs ul li a:visited {
    -webkit-border-top-left-radius: 10px;
    -webkit-border-top-right-radius: 10px;
    -webkit-border-bottom-right-radius: 0px;
    -webkit-border-bottom-left-radius: 0px;
    -moz-border-radius-topleft: 10px;
    -moz-border-radius-topright: 10px;
    -moz-border-radius-bottomright: 0px;
    -moz-border-radius-bottomleft: 0px;
    border-top-left-radius: 10px;
    border-top-right-radius: 10px;
    border-bottom-right-radius: 0px;
    border-bottom-left-radius: 0px;
    display: block;
    text-align: center;
    width: 100px;
    height: 40px;
    line-height: 36px;
    text-transform: uppercase;
    text-decoration: none;
    font-size: 13px;
    font-weight: bold;
    color: #ffffff;
    letter-spacing: 1px;
    outline: none;
    float: left;
    background: #888888;
}

.tabs ul li a:hover {
    background-color: #000000;
}

.tabs ul li a.active, .tabs ul li a.active:visited {
    color: #000000;
    
    background-color: #cccccc;
}

.tabs .content {
    width: 500px;
    background: #cccccc;
    padding: 15px;
    margin: 0;
    -webkit-border-radius: 10px;
    -moz-border-radius: 10px;
  ...

JavaScript

//When tab is clicked pass it to the updateTabs method
$(".tabs .tab a").live("click", function(e) {
    console.log('click: ' + this.href);
    updateTabs($($(this).attr("href")));
});

//Grab hash off URL (default to first tab) and update
$(window).bind("hashchange", function(e) {
    console.log('hashchange: ' + location.hash);
    var anchor = $(location.hash);
    if (anchor.length === 0) {
        anchor = $(".tabs div:eq(0)");
    }
    updateTabs(anchor);
});

//Pass in the tab and show appropriate contents
function updateTabs(tab) {
    $(".tabs .tab a")
        .removeClass("active")
        .filter(function(index) {
            return $(this).attr("href") === '#' + tab.attr("id");
        }).addClass("active");
    $(".tabs .content").hide();
    tab.show();
}

//Fire the hashchange event when the page first loads
$(window).trigger('hashchange');

$('<a />', { 
    id : 'show',
    text : window.location.pathname.indexOf('show/light') > 0 ? 
    'View Full Screen' : 'Edit using jsFiddle', 
    href : window.location.pathname.indexOf('show/light') > 0 ?
    window.location.pathname.replace(/light\/$/gi, "") :
    window.location.pathname.replace(/show\/$/gi, ""),
    target : '_blank'
}).appendTo('body');