jQuery Tabs + iFrame’s

07-06-2014 - Update! I have changed "$tabs.tabs(‘option’, ‘selected’)." to "$tabs.tabs(‘option’, ‘active’)." for the latest versions of jQuery, the old method is no longer reliable.

 

In this tutorial I’m going to talk you through using a great feature of jQuery UI called “tabs” with iFrame’s. Before we get to the actual guide let me first point out that although iFrame’s are greatly shunned by a great number of web developers (including myself) there actually is a great purpose for iFrame’s, it’s just when you use them to build a whole website; for instance a frame for the menu bar, frame for the right column and a frame for the content… Well yeah, go to hell!

Seriously though, iFrame’s are great (if they wasn't, why would they still be in the HTML specifications?), the thing is though, they should only be used when really necessary.

Right! Lets get to the actual point of this post. I was recently trying to get jQuery’s Tabs UI to show an iFrame for each tab – but to not load the iFrame until you actually click on the tab. There were no great tutorials on the internet explaining how to accomplish this or how to get it working and looking good.
After some work though and tinkering with jQuery I finally got a solution together and thought I would share it with everyone who required the same solution as I did.

Step 1: Setting up jQuery UI Tabs

The first thing you are going to want to do is get the jQuery tabs working, download jQuery and then download jQuery UI from the URL’s below. save the jQuery as “jQuery.js”, when you have the jQuery UI you will see several folders in the package. move the “css” and “js” folders into your project and change the link to the correct css and js file in the html given further below.

Download jQuery.
Download jQuery UI. (for this tutorial I used the "smoothness" theme)

Here is the basic setup to get the jQuery UI Tabs working, if you load the html page up in a browser you should see several tabs which you can click to switch between, but no data will appear in any of the tabs.

<html>
 <head>
 <script src="data/js/jquery.js"></script>
 <script src="data/js/jquery-ui.js"></script>
 <link href="data/css/smoothness/jquery-ui.css" rel="stylesheet" type="text/css">

 <script>
 $(document).ready(function() {
 var $tabs = $('#tabs').tabs();
 });
 </script>
 </head>
 <body>
 <div id="tabs">
 <ul>
 <li><a class="tabref" href="#tabs-1">google</a></li>
 <li><a class="tabref" href="#tabs-2">yahoo</a></li>
 <li><a class="tabref" href="#tabs-3">bing</a></li>
 </ul>
 <div id="tabs-1" class="tabMain">
 </div>

 <div id="tabs-2">
 </div>

 <div id="tabs-3">
 </div>
 </div>
 </body>
</html>

Step 2: Implementing iFrames

So now we have the basic tabs working we are going to want to show an iFrame depending on which tab we have selected, the trick is to also not load the iFrame until we select the tab (else we could have quite a number of tabs loading when we hit the page!). To accomplish this we need to capture the mouse key press event, our <a> tags have a class assigned to them called “tabref” which we will use only on iFrame required tabs (this allows you to have tabs that don't iFrame), here is how we do this in jQuery:

$("a.tabref").click(function() {
 //event code
 });

This would go in the $(document).ready under the tabs initialization code like this:

<script>
 $(document).ready(function() {
 var $tabs = $('#tabs').tabs();

 $("a.tabref").click(function() {
 //event code
 });</script>

Ok so now we can do some code when a link on the tab panel is clicked. Now we need to think about how we will get the URL for the iFrame and then build the iFrame into the tabs content.

To hold the URL that the iFrame will load, I have used a HTML attribute called “rel”, so to each <a> tag we will now set a rel tag with the URL to the page we wish to load in the iFrame, like so:

<li><a class="tabref" href="#tabs-1" rel="http://google.co.uk">google</a></li>
<li><a class="tabref" href="#tabs-2" rel="http://yahoo.co.uk">yahoo</a></li>
<li><a class="tabref" href="#tabs-3" rel="http://bing.co.uk">bing</a></li>

Now we can create a function that can grab the “rel” attributes content when we click an <a> tag, and finally to set the panel to a iFrame pointing to that URL. Here is a basic function which will accomplish these tasks:

function loadTabFrame(tab, url) {
 if ($(tab).find("iframe").length == 0) {
 var html = [];
 html.push('<div class="tabIframeWrapper">');
 html.push('<iframe class="iframetab" src="' + url + '">Load Failed?</iframe>');
 html.push('</div>');
 $(tab).append(html.join(""));
 }
 return false;
}

You can see this function needs two variables, the first is the object reference for the <a> tag clicked, and the second is the URL for the iFrame to link to. It’s actually a very simple function and here’s how to call it in your “click” event:

$("a.tabref").click(function() {
 loadTabFrame($(this).attr("href"),$(this).attr("rel"));
});

Congratulations!

We how have a working iFrame Tab UI – BUT WAIT! I’m sure your still not entirely happy with how it functions and how it looks! So lets spruce it up and make it work better in Step 3…

Step 3: Default Tab – Wheres the Iframe?

You may have noticed that when you first load the page a tab is selected as default, but no content or iFrame is shown. This is because we are generating the iFrame when (and only when) we click on a tab. So we need to do a little more code to get the default tabs iFrame loaded (if there is one!) when we first load the site. We can use the same “loadTabFrame"” function!

The first thing we need to do is get the selected tab’s index number, then we would need to use CSS to select the right <li> and finally to grab the <a> object.

Here is a small function that will get the selected tabs index, this would go in the document.ready just below where we initialize the tabs:

function getSelectedTabIndex() {
 return $tabs.tabs('option', 'active').
}

From this function we can now get a hold on the Object for the <a> we want, place this code directly below the code above:

beginTab = $("#tabs ul li:eq(" + getSelectedTabIndex() + ")").find("a");

Now we have the object we require, we can just call our “loadTabFrame” function once on page load to setup that tabs iFrame, place this below the code above:

loadTabFrame($(beginTab).attr("href"),$(beginTab).attr("rel"));

Now you should see the selected tabs iFrame when the page first loads!

Step 4 – Pretty looking iframe’s please!

Ok! So the iFrames are small and un-stylish compared to the actual tabs. Fortunately this can be changed with some nice CSS. Here is some css that will give your iFrames a 100% width, the height however will require a little bit of Javascript as setting a 100% height is not very pleasing.

<style>
 html {
 font-size:10px;
 }

 .iframetab {
 width:100%;
 height:auto;
 border:0px;
 margin:0px;
 background:url("data/iframeno.png");
 }

 .ui-tabs-panel {
 padding:5px !important;
 }
</style>

The background image set to iFrame is there so we can see a loading message until the iFrame has content – alternatively if the iFrame cannot load any content the image can warn that it may have failed. Here is the image I was using, feel free to use it too:

iframeno

 

To set the height requires some Javascript – We need to edit the “loadTabFrame” so when it loads the iFrame it will also set the height of the iFrame:

function loadTabFrame(tab, url) {
 if ($(tab).find("iframe").length == 0) {
 var html = [];
 html.push('<div class="tabIframeWrapper">');
 html.push('<iframe class="iframetab" src="' + url + '">Load Failed?</iframe>');
 html.push('</div>');
 $(tab).append(html.join(""));
 $(tab).find("iframe").height($(window).height()-80);
 }
 return false;
}

So were getting the window height and removing 80px from it so that it now fits more perfectly in the browser window!

Step 5 – Breaking out of the iFrames

Sometimes we wish to break out of the iFrame… I found it a very useful feature when utilizing this code myself. So I though I would include it. Basically a link just above the iFrame can be clicked to take us directly to the iFrames destination URL without using the iFrame itself, this can be accomplished by editing our “loadTabFrame” function so that it places <a> tags which can be clicked to take us to the destination URL if we please, here is the revised code:

function loadTabFrame(tab, url) {
 if ($(tab).find("iframe").length == 0) {
 var html = [];
 html.push('<div class="tabIframeWrapper">');
 html.push('<div class="openout"><a href="' + url + '"><img src="data/world.png" border="0" alt="Open" title="Remove iFrame" /></a></div><iframe class="iframetab" src="' + url + '">Load Failed?</iframe>');
 html.push('</div>');
 $(tab).append(html.join(""));
 $(tab).find("iframe").height($(window).height()-80);
 }
 return false;
}

world.png refers to this image:

world

To make this pretty I have also done some CSS so that the link appears in the tab bar and the iFrame is moved up to look neat, here is the revised CSS code:

<style>
 html {
 font-size:10px;
 }

 .iframetab {
 width:100%;
 height:auto;
 border:0px;
 margin:0px;
 background:url("data/iframeno.png");
 position:relative;
 top:-13px;
 }

 .ui-tabs-panel {
 padding:5px !important;
 }

 .openout {
 float:right;
 position:relative;
 top:-28px;
 left:-5px;
 }
</style>

There we go!

Final Code

For those of you who could not follow or did not have the time, here is a full final cut of the code:

<html>
 <head>
 <script src="data/js/jquery.js"></script>
 <script src="data/js/jquery-ui.js"></script>
 <link href="data/css/smoothness/jquery-ui.css" rel="stylesheet" type="text/css">
 <style>
 html {
 font-size:10px;
 }

 .iframetab {
 width:100%;
 height:auto;
 border:0px;
 margin:0px;
 background:url("data/iframeno.png");
 position:relative;
 top:-13px;
 }

 .ui-tabs-panel {
 padding:5px !important;
 }

 .openout {
 float:right;
 position:relative;
 top:-28px;
 left:-5px;
 }
 </style>
 <script>
 $(document).ready(function() {
 var $tabs = $('#tabs').tabs();

 //get selected tab
 function getSelectedTabIndex() {
 return $tabs.tabs('option', 'active');
 }

 //get tab contents
 beginTab = $("#tabs ul li:eq(" + getSelectedTabIndex() + ")").find("a");

 loadTabFrame($(beginTab).attr("href"),$(beginTab).attr("rel"));

 $("a.tabref").click(function() {
 loadTabFrame($(this).attr("href"),$(this).attr("rel"));
 });

 //tab switching function
 function loadTabFrame(tab, url) {
 if ($(tab).find("iframe").length == 0) {
 var html = [];
 html.push('<div class="tabIframeWrapper">');
 html.push('<div class="openout"><a href="' + url + '"><img src="data/world.png" border="0" alt="Open" title="Remove iFrame" /></a></div><iframe class="iframetab" src="' + url + '">Load Failed?</iframe>');
 html.push('</div>');
 $(tab).append(html.join(""));
 $(tab).find("iframe").height($(window).height()-80);
 }
 return false;
 }
 });
 </script>
 </head>
 <body>

 <div id="tabs">
 <ul>
 <li><a class="tabref" href="#tabs-1" rel="http://google.co.uk">google</a></li>
 <li><a class="tabref" href="#tabs-2" rel="http://yahoo.co.uk">yahoo</a></li>
 <li><a class="tabref" href="#tabs-3" rel="http://bing.co.uk">bing</a></li>
 </ul>
 <div id="tabs-1" class="tabMain">
 </div>

 <div id="tabs-2">
 </div>

 <div id="tabs-3">
 </div>
 </div> 

 </body>
</html>

Conclusion

There we have it! A fully working solution with some nifty extra functionality and nice styling.

Here was my end solution:

image

The code works flawlessly and I don't see any horrible layout problems either, the solution works in all modern browsers (FF – IE 9 – Safari – Chrome) and doesn't overload your browser by loading all the iFrame’s at once!

If you have any feedback and/or suggestions please post a comment, it would be awesome to refine this tutorial a little more if required and fix anything I may have goofed on. Also post some screenshots of your final solution and modifications to the code!

And don't forget to give some credit if this has helped you out Winking smile

Facebooktwitterredditpinterestlinkedinmail
Author: Dean WilliamsI'm a Web Developer, Graphics Designer and Gamer, this is my personal site which provides PHP programming advice, hints and tips

Post Tags:
, , ,
0 0 votes
Article Rating
Subscribe
Notify of
26 Comments
Inline Feedbacks
View all comments

hey thanks for nice example..u saved my day..thank you once again.

how can i make the tab close when change to other tab.
example when i go at yahoo the bing will close.
if i go to bing and back to yahoo the page will load again.

another one, how can i make this tab combine with normal ui tab?

That wont work . The image will show bellow the content

Hi I,m building a website and how can i open a new tab called "exercises" when i click in one link "Exercises" inside tab "HOME" to load page"exercises.html" for example? :?:
Thanks in advance for your attention

where is the data/css/smoothness/jquery-ui.css?

Dean,

Thanks for this great tutorial/code. I was just wondering if anyone else was having this problem: the bing page works but the google and the yahoo page show nothing in the iframe. When I went into the code and changed one of the links to another site, it broke the iframe.
Any help on this matter would be greatly appreciated! Thanks

This is a great tutorial, thanks!

I have replaced your loading image with another one. However how do I get that to disappear once the iframe has loaded?

What I meant by the post below is that the loading image you have provided still displays in the background after the iFrame has loaded.

I have a different theme to you and therefore I have padding before the iFrame and you can see the loading image appearing behind the iFrame after it has loaded.

Any ideas? Ideally I would like an animated circle showing that the data has loaded.

I have tried a few different things, but these rely on using the SRC rather than placing the URL in the REL.

Help would be really appreciated.

Thanks
Nick

Thanks a million for your brilliant tutorial - it was a huge help! You are a genius :grin:

Thanks for tutorial.
I have a question about this tabs.

If this tabs is used for iframe tabs video, why can not stop the video if I open another tab.
Please clue, what needs to be changed on the tabs script

This works great in Chrome but not IE8??

Any suggestions?

hey friend.. thank you for lesson.. i will use in my project

Hi! This is a great Tutorial!

Almost work perfectly when I tried it, the only small issue is that I'm using JQuery UI 1.10.3 and the getSelectedTabIndex() function $tabs.tabs('option', 'selected') does not work.

But it just need to be changed to $tabs.tabs('option', 'active').

while I do admire your coding, I have to say I wanna slap the shit out of people that dont use public cdn's or jquery versions in there code. You used generic jquery and jquery ui references, so we are left guessing what to use and having to modify the code to public cdns before running locally. It would save us all alot of time if people would start using public CDN's in tutorials.

hi deano

Can i see it working - do you have a link to a demo?

Regards

didi

Hi,

Thanks a lot for this useful post. : )

Many many thanks. It's really useful.

Is there a way to make the first tab display upon load and the subsequent load upon clicking?