Skip to content

Instantly share code, notes, and snippets.

@malihu
Created October 1, 2012 14:49
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save malihu/3812245 to your computer and use it in GitHub Desktop.
Save malihu/3812245 to your computer and use it in GitHub Desktop.
Fully commented code for the tabs.js script
(function($){
$.fn.Tabs=function(speed){ /* tabs transition speed parameter */
return this.each(function(){
/* define/cache variables */
var tabs=$(this),
tabsLabels=tabs.children("ul"),
tabLabel=tabsLabels.find("a"),
tabsContent=tabs.children("div"),
tabLink,
tabsLoader=tabsContent.children(".ajax-loader"); /* define ajax loader element */
if(!speed){
speed=0; /* if speed parameter is not set, defaults to zero */
}
/* add tabs content markup if necessary */
if(tabsContent.length===0){ /* tabs markup does not exist. Create it. */
tabs.append("<div />");
tabsContent=tabs.children("div");
/* no static content exists. Tab content will load via ajax */
tabsLabels.children("li").each(function(){
/* apply an ajax class so we can identify later which method
we're going to use (static or ajax) */
tabsContent.append("<div class='ajax-tab-content' />");
});
}else{ /* tabs markup exists */
tabsContent.children("div").each(function(){
/* tabs markup exists but it's empty. Tab content will load via ajax */
if($.trim($(this).text())===""){
$(this).addClass("ajax-tab-content");
}
});
}
/* if .ajax-loader doesn't exist and ajax content will be used, create the preloader element */
if(tabsLoader.length===0 && tabsContent.children("div.ajax-tab-content").length>0){
tabsContent.append("<span class='ajax-loader' />"); /* create it */
tabsLoader=tabsContent.children(".ajax-loader"); /* cache it */
}
/* if no .active-tab class exists, set the first tab as active */
if(tabsLabels.find(".active-tab").length===0){
tabsLabels.children("li:first").addClass("active-tab");
}
tabLink=tabsLabels.find(".active-tab a"); /* cache the active tab anchor element */
tabsContent.css({"height":tabsContent.height()}); /* set the initial height value for animation */
/* call the LoadTabContent function that loads the tab content
The first parameter is the returned value of the FindTabContent function
that finds the target tab content */
LoadTabContent(FindTabContent(tabLink),tabLink);
/* tab click event */
tabLabel.click(function(e){
e.preventDefault();
tabLink=$(this); /* store new tabLink value */
LoadTabContent(FindTabContent(tabLink),tabLink); /* load tab content according to clicked anchor (tabLink) */
});
/* function: find tab content from href value or DOM index */
function FindTabContent(tabLink){
var targetTab,
tabID=tabLink.attr("href");
/* check if href attribute exists, its value is not "#" but starts with "#"
and a div with an equivalent id exists */
if(tabID && tabID!="#" && tabID.substring(0)==="#" && tabsContent.find(tabID).length!=0){
/* find target div based on href value */
targetTab=tabsContent.find(tabID);
}else{
/* find target div based on DOM index */
tabID=tabLink.parent().index();
targetTab=tabsContent.children("div").eq(tabID);
}
return targetTab;
}
/* function: load tab content */
function LoadTabContent(targetTab,tabLink){
/* find current active tab label and content */
var activeTab=tabsLabels.find(".active-tab"),
activeTabContent=tabsContent.find(".active-tab-content");
if(activeTabContent.length===0){
/* if .active-tab-content not found, active tab is the target tab */
activeTabContent=targetTab;
}
activeTabContent.stop().fadeOut(speed,function(){ /* fade-out current active tab */
activeTab.add(activeTabContent).removeClass("active-tab active-tab-content"); /* remove current active tab */
tabLink.parent().addClass("active-tab"); /* set active tab */
/* check if content will be static or loaded via ajax */
if(targetTab.is(".ajax-tab-content")){ /* ajax content */
tabsLoader.stop().fadeIn(speed); /* fade-in ajax preloader */
targetTab.load(tabLink.attr("href"),function(){ /* load the content in targetTab */
/* make sure all images are fully loaded before revealing tab content */
var targetTabImages=targetTab.find("img"),
targetTabImagesLoaded=0;
if(targetTabImages.length>0){ /* if images exists preload them */
targetTabImages.bind("load",function(){
targetTabImagesLoaded++
/* if final image is fully loaded, fade-out the preloader and
show tab content via the ShowTabContent function */
if(targetTabImagesLoaded>=targetTabImages.length){
tabsLoader.stop().fadeOut(speed);
ShowTabContent();
}
});
}else{ /* ajax content without images */
/* fade-out the preloader and show tab content via the ShowTabContent function */
tabsLoader.stop().fadeOut(speed);
ShowTabContent();
}
});
}else{ /* static content */
ShowTabContent(); /* show tab content via the ShowTabContent function */
}
/* function: show tab content */
function ShowTabContent(){
/* add .active-tab-content class to the target div and
set it to block so we can animate its height value.
Apply a zero opacity so we can fade it in via $.animate({opacity}) */
targetTab.addClass("active-tab-content").css({"opacity":0,"display":"block"});
tabsContent.stop().animate({height:targetTab.outerHeight()},speed,function(){ /* animate wrapper div height */
targetTab.stop().animate({opacity:1},speed); /* fade-in target tab content */
});
}
});
}
});
}
})(jQuery);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment