Switch content (unobtrusive js)

I've realised that a lot of the javascript on this site is kind of out-of-date. The trend these days is towards 'unobtrusive' javascript, which basically means that you don't add anything extra to the HTML of the page - just like with CSS. I think this is a good trend and I hope to do all (or most) javascript this way in future.

Explanation : Part 1

When the page loads, the hidestories() function is called (with the 'window.onload' bit). This finds the #stories div then hides all the divs inside that with the class 'story' and makes them 'display:none;'. Then, to show the first story onload, a variable is sent to the stories() function.

The stories() function assigns another function (with no name) to the onclick event of each of the links at the top. It finds the element with the id #thebuttons and identifies the links in that. The function that is attached to the links first runs the hidestories() function, then takes the part of the link after the '#' and turns it into a variable. The div that was being linked to is then displayed ('display:block;') and the link itself returns false.

Explanation : Part 2

The good thing about this is that if javascript is disabled, the links will work as normal and all the content will still be readable.

The bad thing about this - just like on (the page I had here before) - is that when the page first loads, you can see all of the content for a second before the javascript kicks in and hides it. If you're on an intranet and are able to control the browsers, or if you just don't care about those without javascript, you can fix this by setting the class 'story' to 'display:none;' in your CSS.

Explanation : Part 3

Another small point is that I haven't added anything here that highlights the current content in the menu at the top. It's not too difficult to do, I just wanted to keep this as simple as possible. Here's an example.

Of course, you can also do this whole 'switch content' thing with AJAX. My demo uses AJAX (basically javascript, php, and the xml 'httprequest') to change the content of the page by only refreshing the content part. This also doesn't work if javascript is disabled, so my demo uses PHP to include the content into a template page if the javascript fails.

HTML
<h1>Switch content (unobtrusive js)</h1>
<p>I've realised that a lot of the javascript on this site is kind of
out-of-date. The trend these days is towards 'unobtrusive' javascript, which basically means that you don't add anything extra to the HTML of
the page - just like with CSS. I think this is a good trend and I hope
to do all (or most) javascript this way in future.</p>
<ul id="thebuttons">
<li><a href="#storyA">Story A</a></li>
<li><a href="#storyB">Story B</a></li>
<li><a href="#storyC">Story C</a></li>
</ul>
<div id="stories">
<div id="storyA" class="story">
<h2>Explanation : Part 1</h2>
<p>When
the page loads, the hidestories() function is called (with the
'window.onload' bit). This finds the #stories div then hides all the
divs inside that with the class 'story' and makes them 'display:none;'.
Then, to show the first story onload, a variable is sent to the stories() function.</p>
<p>The
stories() function assigns another function
(with no name) to the onclick event of each of the links at the top. It
finds the element with the id #thebuttons and identifies the links in
that. The function that is attached to the links first runs the
hidestories() function, then takes the part of the link after the '#' and turns it into a variable. The div that was being linked
to is then displayed ('display:block;') and the link itself returns
false.</p>
</div>
<div id="storyB" class="story">
<h2>Explanation : Part 2</h2>
<p>The
good thing about this is that if javascript is disabled, the links will
work as normal and all the content will still be readable.</p>
<p>The bad thing about this - just like on (<a href="http://bonrouge.com/br.php?page=switchcontent">the page I had here before</a>)
- is that when the page first loads, you can see all of the content for
a second before the javascript kicks in and hides it. If you're on an
intranet and are able to control the browsers, or if you just don't
care about those without javascript, you can fix this by setting the
class 'story' to 'display:none;' in your CSS.</p>
</div>
<div id="storyC" class="story">
<h2>Explanation : Part 3</h2>
<p>Another
small point is that I haven't added anything here that highlights the
current content in the menu at the top. It's not too difficult to do, I
just wanted to keep this as simple as possible. <a href="br.php?page=switchcontent4">Here's an example</a>.</p>
<p>Of course, you can also do this whole 'switch content' thing <a href="http://bonrouge.com/br.php?page=ajaxswitch">with&nbsp;AJAX</a>.
My demo uses AJAX (basically javascript, php, and the xml 'httprequest')
to change the content of the page by only refreshing the content part.
This also doesn't work if javascript is disabled, so my demo uses PHP
to include the content into a template page if the javascript fails.</p>
</div>
</div>
CSS
#thebuttons {
list-style:none;
width:24em;
margin:auto;
}
#thebuttons li {
float:left;
width:8em;
font-weight:bold;
background-color:yellow;
padding:0.5em 0;
margin:1em auto;
text-align:center;
}
#stories {
width:30em;
margin:1em auto;
border:1px solid purple;
clear:left;
padding:1em;
}
Javascript
function hidestories() {
var divs=document.getElementById('stories').getElementsByTagName('div');
for (j=0; j<divs.length; j++) {
var rE = new RegExp("(^|\\s)" + 'story' + "(\\s|$)");
if (rE.test(divs[j].className)) {
divs[j].style.display="none";
}
}
}

function stories(first) {
var thebuttons=document.getElementById('thebuttons').getElementsByTagName('a');
for (i=0; i<thebuttons.length; i++) {
thebuttons[i].onclick=function() {
hidestories();
var thestory=(this.href).split("#",2)[1];
document.getElementById(thestory).style.display="block";
return false;
}
}
if (first) {
var firstone=document.getElementById('stories').firstChild;
if (firstone.nodeType != 1) {firstone = firstone.nextSibling;}
firstone.style.display="block";
}
}
window.onload=function() {
hidestories();
stories(1);
}

Comments

#1
2006-10-16 Louis says :

Just used this script as a much needed solution on a website I'm designing. Quick note to say thanks for the effort you put into writing it.

Cheers

#2
2006-12-17 Todd says :

What if I wanted to use this for videos set to autoplay? Each time I'd click a new video, if the current one is still playing, it will continue to do so in the background, behind the newer video. Any remedy for this?

Love the script by the way. Thanks so much.

#3
2007-02-05 Sean says :

I spent 6 hours searching for a script similar to this....thank you so much for posting and sharing......

#4
2007-09-11 brad says :

loads of useful stuff here, thanks for taking the time to make it available.

Brad

#5
2008-03-17 Josh says :

I'm using this concept in my page, but im trying to use the <li><a href="#storyA">Story A</a></li> part inside a "story" but it wont change to the new content, any suggestions please email me at x_anubis@msn.com

#6
2008-06-30 Jen says :

Can I use this script and have other pages link to it? I am thinking of using this code as my portfolio page. Listing all the logos of companies i done in storyA then a description of each of those companies in other stories. But can i link to a specific story on other parts of my page... like portfolio.html#storyC or something like that?

This site rocks! Thank you for all your help!

#7
2008-06-30 Jen says :

This is an awesome script! Thank you for sharing!

I am wanting to use it on a portfolio page, I have it working on the list of companies on the side. But I have storyA with all the logos of the companies, I would like to make the choice of clicking on the tex link on the side (your script with <ulid="thebuttons">
<li><a href="#storyA">Story A</a></li> ) OR give the option of clicking on the logo in storyA. That would then display the story of their choice either way.
How in the world do i do that?! I cant seem to figure it out!

Thanks so much for all your scirpts! They are awesome!
Jen

#8
2008-06-30 BonRouge says :

Jen,
I've played around with it a little. See if this helps.

#9
2008-06-30 Jen says :

Bon,
Thank you so much for helping me out! I have been pulling my hair out all day!
It does indeed show the storyB, but it doesnt get rid of storyA.
Maybe the probelm is that the link to storyB IS IN storyA. Because storyA contains logos and on click takes them to other stories about that specific company.)
It sortof works. just didnt hide storyA.

Any ideas?
Jen

#10
2008-06-30 Jen says :

I TAKE IT ALL BACK!!!!
It worked!!! WHOOO-HOOOO!!!
You are a genious!
I just forgot to change the stories to tstories!

YOU ROCK!!! THANK YOU SOOOO MUCH!!!!
Jen

#11
2008-07-01 BonRouge says :

Jen,
Glad it worked for you. smile

#12
2008-09-05 Lalas says :

Wow, awesome script!!! Thanks!!!

But I have a problem. I'm trying to use it for different parts in the same webpage but it doesn't work!!! Please help!!!

#13
2008-11-17 The-Jester666 says :

Thanks for this awesome script smile.

#14
2008-12-06 Sunny says :

Hi thanks for the wonderful script.

But i need ur help.

I have loaded a video in 4 div.
it works fine in mozilla firefox, But it having a problem in internet explorer.

in Internet explorer the video is playing in background. if we load another div the first div's video is playing in background.
It is not stoping.

but in firefox it stops.

would u have script to unload video after another div loads

#15
2008-12-06 BonRouge says :

Sunny,
I'm sorry. If I were you I'd use different pages (with PHP includes) rather than this script for videos.

#16
2009-01-14 sunny says :

thanks i will try it.
ok bye

#17
2009-02-10 Nick says :

Is it possible to display a default story(intro) when the page first loads rather than a blank story?

#18
2009-02-10 Nick says :

my problem is the story divs get inserted into another div container, I believe this is causing the onload story not to load.

#19
2009-02-10 Nick says :

Fixed it, I just needed to add another .firstChild propertie - E.G. var firstone=document.getElementById('stories').firstChild.firstChild;

#20
2009-06-25 Kirby says :

What do I name the css and javascipt files?

#21
2009-06-26 BonRouge says :

Kirby,
You can call them anything you like.
See this page:
http://bonrouge.com/~externalfiles

#22
2009-08-13 Holger K. says :

Thanks a lot, this is exactly what ive been looking for - awesome smile

- Holger K. www.cypher1.de

#23
2009-09-15 Marcos says :

First of all, thank you very much, it is a great solution.

Secondly, I'm having a hard time making it work when the page url is something in the form of "*.html". Otherwise, it works like a charm.

I imagine it has something to do with '(this.href).split("#",2)[1];', right? But JScript isn't my forte. Could you help me?

Again, thanks for your script!

#24
2009-09-15 BonRouge says :

Marcos,
I can't see how an '.html' extension would affect the script. If you show me the specific problem, maybe I could help.

#25
2009-09-15 Marcos says :

Problem solved. I was making use of your script in my girlfriends blog. The issue was that I had a previous JScript declaration under a conditional <b:if> and -as you have probably figured by now- I put yours there too. Dumb, I know.

Anyway, thanks one more time.

#26
2011-11-03 Varoun says :

Thanks. Very useful! Great website background as well!

#27
2012-04-10 Oscar says :

I used your script on a website and it works great google map v2 (with absolute height and width). I am trying to migrate to google map v3 but the map will not show correctly in the hidden tab. Is there away to make it work with your script? I am new to javascript and any help will be great. thx.

#28
2013-08-17 Mandy says :

I know this is an old post but I have tried the script on ie8 and it doesn't work. It works fine in firefox and safari. If you can help comment on this it will be great. thx.

#29
2013-08-17 BonRouge says :

Mandy,
Are you sure about this? I've just opened up Internet Explorer (10) and this page works fine. Maybe IE10 is less bad than IE8, but I doubt it.

#30
2014-01-07 Axl says :

This is the answer! Thank you so much, bro!

Comment form

Please type the word 'curry' here:

BB code available :

  • [b]...[/b] : bold
  • [it]...[/it] : italic
  • [q]...[/q] : quote
  • [c]...[/c] : code
  • [url=...]...[/url] : url