Script for changing content

I don’t know javascript very well and have been searching the net for a script or a starting point, but found nothing.

Part of a website I am doing for a family member requires that a link be clicked in the submenu and depending on what is clicked, it will control what is shown in the content section of the page. Click one link and a poster is displayed, click the other link and writing is displayed, all on the one page.

Can anyone help me with this? I thought it would be something used a lot, but perhaps I am using the incorrect description in all my searching.

Thanks,
Vicki

  1. put all the content for each link in a separate container <div>

  2. use css to hide all the containers in 1) on page load

  3. as each link is clicked, use javascript to hide the containers in 1) again (which will include the current visible one) and then set the display property for the container associated with the clicked link to “block” to make it visible

I wouldn’t use css to hide the container, because then you see nothing when javascript is not available.

Here’s some sample HTML content:


<ul id="nav">
    <li><a href="#poster">Poster</a></li>
    <li><a href="#writing">Writing</a></li>
</ul>
<div id="poster">
    A poster is shown here.
</div>
<div id="writing">
    Some writing is shown here.
</div>

When the page loads, you’re going to want to do several things.

  1. hide the sections that are linked to from the navigation
  2. If the location bar links to a section, show that one section
  3. capture clicks in the navigation so that you can hide other sections and show the clicked section

window.onload = function () {
    var sectionId = 'nav';
    hideLinkedSections(sectionId);
    if (location.hash) {
        showLinkedSection(location.hash);
    }
    document.getElementById(sectionId).onclick = handleSectionClicks;
}

Here’s how you can hide all of the sections:


function hideLinkedSections(sourceId) {
    var nav = document.getElementById(sourceId),
        i,
        links = nav.getElementsByTagName('a'),
        id;
    for (i = 0; i < links.length; i += 1) {
        id = links[i].href.split('#')[1];
        if (document.getElementById(id)) {
            document.getElementById(id).style.display = 'none';
        }
    }
}

When showing a section, because it could be ‘#poster’ from the location bar, or from a links href value, the function should accept that hash value and process things from there.


function showLinkedSection(hash) {
    var id = hash.split('#')[1];
    document.getElementById(id).style.display = '';
}

With the click handler, the top two thirds of it is just making sure that the click occurred on a linked element.


function handleSectionClicks(evt) {
    evt = evt || window.event;
    var targ = evt.target || evt.secElement;
    if (targ.nodeType === 3) {
        targ = targ.parentNode;
    }
    if (targ.nodeType === 1 && targ.nodeName === 'A') {
        hideLinkedSections(this.id);
        showLinkedSection(targ.href);
    }
}

Here’s a sample test page that you can use to play around with things.
Please keep in mind that the script code really should be saved out to an external file, such as js/script.js


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Test page</title>
<body>
<ul id="nav">
    <li><a href="#poster">Poster</a></li>
    <li><a href="#writing">Writing</a></li>
</ul>
<div id="poster">
    A poster is shown here.
</div>
<div id="writing">
    Some writing is shown here.
</div>
<script type="text/javascript">
function hideLinkedSections(sourceId) {
    var nav = document.getElementById(sourceId),
        i,
        links = nav.getElementsByTagName('a'),
        id;
    for (i = 0; i < links.length; i += 1) {
        id = links[i].href.split('#')[1];
        if (document.getElementById(id)) {
            document.getElementById(id).style.display = 'none';
        }
    }
}
function showLinkedSection(hash) {
    var id = hash.split('#')[1];
    document.getElementById(id).style.display = '';
}
function handleSectionClicks(evt) {
    evt = evt || window.event;
    var targ = evt.target || evt.secElement;
    if (targ.nodeType === 3) {
        targ = targ.parentNode;
    }
    if (targ.nodeType === 1 && targ.nodeName === 'A') {
        hideLinkedSections(this.id);
        showLinkedSection(targ.href);
    }
}
window.onload = function () {
    var sectionId = 'nav';
    hideLinkedSections(sectionId);
    document.getElementById(sectionId).onclick = handleSectionClicks;
    if (location.hash) {
        showLinkedSection(location.hash);
    }
}
</script>
</body>
</html>

yes that is true :agree: for on the most likely very few occasions javascript is turned off in the requesting browser, but if you initially display all the sections and hide them on window.onload you could get a brief flicker effect in the browser (when js is on) due to all the sections being visible for a split second and then being hidden which a client might not want to see.

so I guess it boils down to client requirements.

There are fancier techniques that can be used to avoid a potential flicker.

One example that come to mind are to hide the sections when the DOM is ready, which occurs long before the onload event. That can be done either by placing the script directly at the end of the body, or by attaching to the ondomcontentloaded event.

Beyond that you could set up a timed event that triggers every 25 milliseconds that searches for content sections and hides them, which on page load is then cancelled.

Those are at the far ends of reality though, as the situations which require such a speedy response are few and far between.

ok thanks :slight_smile:

but it sounds like it could be “messy” or at the very least means extra code.

I suppose that’s another reason why I don’t jump anymore at getting involved in websites that require non-javascript browser support.

Some scripting can be dramatically simplified with the use of libraries.

When using jQuery for example, all of the scripting in post #3 can be entirely replaced with:


$(function () {
    // attach nav click event
    $('#nav').click(function (evt) {
        // hide linked-to sections
        $('#nav a').each(function () {
            $(this.hash).hide();
        });
        // show clicked link section
        $(evt.target.hash).show();
    }).click(); // trigger on page load
    // Show if page loaded with a selected section
    $(location.hash).show();

});

yes that is true for on the most likely very few occasions javascript is turned off in the requesting browser, but if you initially display all the sections and hide them on window.onload you could get a brief flicker effect in the browser (when js is on) due to all the sections being visible for a split second and then being hidden which a client might not want to see.

I’ve read this here a couple of times now.

I did a similar exercise myself some time ago. Link here http://www.pixel-shack.com/critter/DPS.html

Buttons on the bottom to switch styles or alternatively use the manual preferences route.

Had no real issues with flicker, but then I was only using hand rolled code, so not waiting for larger libraries to load.

My initial thought about the OP’s question is whether CSS might be a better route? Negative margins maybe? Then you’re covered either way.

Just a thought.

RLM

For a CSS solution, you need not look much further than tabbed pages.

http://www.stunicholls.com/various/tabbed_pages.html

The tabs along the top can be changed to be a vertical list for navigation, or to any other form of presentation that you require.

I’m :confused2

A pure css solution to the OP’s situation or to flicker?

those tabs still require javascript to be enabled.

in my FF3.6 they work fine with js enabled, but if I turn js off I can’t move off the first tab.

It was supposed to be a more CSS way of changing the content

How about these 7 examples which are css-only? The last ones appears to be the winner so far, in terms of CSS-only techniques.
http://css-tricks.com/examples/CSSTabs/

Going back to javascript-based techniques, it’s hard to get much simpler than the jQuery-UI tabs.


$('#nav').tabs();

Thank you everyone for your suggestions. I will play around with the code provided and check all the links you sent. I’m sure one of them will be perfect for me.

Vicki