views:

288

answers:

2

Hi - I have little piece of javascript to show/hide divs based on which link is clicked in a list. Its not very eligant, but it works fine. What I'd like to do is to assign an active state the a list item depending on which div is showing. Here is my JS and HTML:

var ids=new Array('section1','section2','section3','section4');

function switchid(id){  
    hideallids();
    showdiv(id);
}

function hideallids(){
    //loop through the array and hide each element by id
    for (var i=0;i<ids.length;i++){
        hidediv(ids[i]);
    }         
}

function hidediv(id) {
    //safe function to hide an element with a specified id
        document.getElementById(id).style.display = 'none';
}

function showdiv(id) {
    //safe function to show an element with a specified id        
        document.getElementById(id).style.display = 'block';
}

html:

<ul>
<li class="activeItem"><a href="javascript:switchid('section1');">One</a></li>
<li><a href="javascript:switchid('section2');">Two</a></li>
<li><a href="javascript:switchid('section3');">Three</a></li>
<li><a href="javascript:switchid('section4');">Four</a></li>
</ul>

<div id="section1" style="display:block;">1111111</div>
<div id="section2" style="display:none;">2222222</div>
<div id="section3" style="display:none;">3333333</div>
<div id="section4" style="display:none;">4444444</div>

When section 2 (or whichever) is clicked, I'd like the class "activeItem" to be removed from the li it is currently on and applied to the current li. Is this possible with javascript? I think it is, but I can't figure out how to implement it client side.

Thanks!

+3  A: 

If you're able to use jQuery (or something similar) as it has this ability built in: http://docs.jquery.com/Attributes - addClass/removeClass

Jonathan
...also $('#myDiv').hide() / $('#myDiv').show() eliminates your functions.
Diodeus
I agree. Another option is Mootools (http://mootools.net/docs/core) which has easy ways of doing this too with addClass and removeClass. It's 2010, no need to write JS from scratch.
Randy Simon
Here is my concern... if I can write this in plain vanilla JS that takes 15 lines of code vs. doing it in half that with jQuery, won't I still be better off with the JS simply because I won't have to reference the jQuery code base. In other words, if I'm not doing anything fancy, won't using jQuery be heavier for the client?
The compressed jQuery is 24kb, so not much of a hit. Some reading, http://www.smashingmagazine.com/2010/02/22/the-seven-deadly-sins-of-javascript-implementation/ - in particular, browser specific code and playing nice with other scripts.
Jonathan
Fair point. I also read about linking to google's jQuery code base in stead of hosting the file on your own server. Seems like lots of people already have it cached from google. Thanks for the link.
+2  A: 

Change your anchors to use the onclick event instead of the href javascript code.

<a onclick="switchid('section1');return false;">One</a>

Then pass the argument this into your switchid function. this is a javascript keyword which in this scenario refers to the element (a).

<a onclick="switchid('section1', this);return false;">One</a>

Now to make the switchid function modify the list.

function switchid(id, el){  
    hideallids();
    showdiv(id);

    // rejiggered for text nodes
    var li = el.parentNode.parentNode.childNodes[0];
    while (li) {
        if (!li.tagName || li.tagName.toLowerCase() != "li")
            li = li.nextSibling; // skip the text node
        if (li) {
            li.className = "";
            li = li.nextSibling;
        }
    }

    el.parentNode.className = "activeItem";
}

Try it out: http://jsbin.com/esazu3/edit

Joel Potter
Joel - This works great! Thanks for your help. It looks like there is an empty function at the top of your linked example and a reference to jquery. Your example seems to work fine with the function removed and no link to jquery.It wonder if doing this with jQuery would be better. What do you think? I would imagine it could be done with less code, but then again the browser would have to load all the jQuery code base, right? I'm not well versed at Javascript, so please forgive my ignorance.Thanks again!
Those jquery references were just in there by default. They're not necessary for this code to work. Jquery would simplify your task a bit, but I don't recommend learning jquery until you feel you have a good grasp of the underlying foundation of javascript. No need to be a js expert, just understand the basics of events, json, and asynchronous vs synchronous. Then go learn jquery. I can't count the times I've heard someone ask how to perform a task in jquery that was trivially simple in plain javascript.
Joel Potter
Hey Joel, is there an easy way to have a link open one of these tabs? I'm trying to set up a link from another page to a specific tab. I would guess it would be possible by passing something into the query string but I just don't know. I've asked the question here: http://stackoverflow.com/questions/2321932/javacript-show-hid-div-and-change-a-css-class-based-on-which-div-is-visible
sorry, wrong link: http://stackoverflow.com/questions/2740753/linking-to-a-section-of-a-site-that-is-hidden-by-a-hide-show-javascript-function
@hollyb. Yes, it possible. See Nick's answer here: http://stackoverflow.com/questions/2740377/how-to-link-to-specific-anchor-in-table-with-jquery/2740392#2740392 (minus the jquery).
Joel Potter
I think I've gotten in a bit over my head as I'm not sure how to convert the jQuery to straight JS. Thanks tho, I'm sure I'll get it worked out.
@hollyb. Just add an `onload="myfunction()"` to your body and `function myfunction() { if(location.hash != '') { hideallids(); showdiv(location.hash.replace("#", "")); } }`.
Joel Potter