SitePoint Sponsor

User Tag List

Results 1 to 7 of 7
  1. #1
    SitePoint Enthusiast Pure L's Avatar
    Join Date
    Oct 2007
    Posts
    47
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    There's gotta be a better way to do this??

    I'm basically just changing the style of 6 divs to "display:block" or "display:none" using some simple javascript.

    I'm willing to bet I'm doing it the hard way, however.

    Perhaps using "this" somehow?

    Any help is much appreciated. Thanks.

    ---------------------------------



    Here's the html (the divs I'm hiding and/or making visible depending on what menu item was clicked):

    <div id="welcomeDiv"><h1>Welcome to this site!</h1></div>
    <div id="aboutDiv">About info goes here....</div>
    <div id="servicesDiv">Services info goes here.....</div>
    <div id="pricingDiv">Pricing info goes here.....</div>
    <div id="testimonialsDiv">Testimonials info goes here....</div>
    <div id="makeAnAppointmentDiv">Make an Appointment info goes here.....</div>


    Here's the js:

    Code:
    <script>
    function showAbout()
    {
    var aboutDiv = document.getElementById("aboutDiv").style.display=("block");
    var servicesDiv = document.getElementById("servicesDiv").style.display=("none");
    var pricingDiv = document.getElementById("pricingDiv").style.display=("none");
    var testimonialsDiv = document.getElementById("testimonialsDiv").style.display=("none");
    var welcomeDiv = document.getElementById("welcomeDiv").style.display=("none");
    var makeAnAppointmentDiv = document.getElementById("makeAnAppointmentDiv").style.display=("none");
    }
    function showServices()
    {
    
    var servicesDiv = document.getElementById("servicesDiv").style.display=("block");
    var aboutDiv = document.getElementById("aboutDiv").style.display=("none");
    var pricingDiv = document.getElementById("pricingDiv").style.display=("none");
    var testimonialsDiv = document.getElementById("testimonialsDiv").style.display=("none");
    var welcomeDiv = document.getElementById("welcomeDiv").style.display=("none");
    var makeAnAppointmentDiv = document.getElementById("makeAnAppointmentDiv").style.display=("none");
    }
    function showPricing()
    {
    
    var pricingDiv = document.getElementById("pricingDiv").style.display=("block");
    var servicesDiv = document.getElementById("servicesDiv").style.display=("none");
    var aboutDiv = document.getElementById("aboutDiv").style.display=("none");
    var testimonialsDiv = document.getElementById("testimonialsDiv").style.display=("none");
    var welcomeDiv = document.getElementById("welcomeDiv").style.display=("none");
    var makeAnAppointmentDiv = document.getElementById("makeAnAppointmentDiv").style.display=("none");
    }
    function showTestimonials()
    {
    var testimonialsDiv = document.getElementById("testimonialsDiv").style.display=("block");
    var pricingDiv = document.getElementById("pricingDiv").style.display=("none");
    var servicesDiv = document.getElementById("servicesDiv").style.display=("none");
    var aboutDiv = document.getElementById("aboutDiv").style.display=("none");
    var makeAnAppointmentDiv = document.getElementById("makeAnAppointmentdiv").style.display=("none");
    var welcomeDiv = document.getElementById("welcomeDiv").style.display=("none");
    }
    function showMakeAnAppointment()
    {
    var makeAnAppointmentDiv = document.getElementById("makeAnAppointmentDiv").style.display=("block");
    var testimonialsDiv = document.getElementById("testimonialsDiv").style.display=("none");
    var pricingDiv = document.getElementById("pricingDiv").style.display=("none");
    var servicesDiv = document.getElementById("servicesDiv").style.display=("none");
    var aboutDiv = document.getElementById("aboutDiv").style.display=("none");
    var welcomeDiv = document.getElementById("welcomeDiv").style.display=("none");
    }
    </script>

  2. #2
    SitePoint Guru
    Join Date
    Apr 2006
    Posts
    802
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If you assign your divs a classname, say 'showBLockCss',
    you can loop through the divs and look for that class.
    Assuming you have a select menu whose values are ids,
    the select's onchange handler can set the selected div's display to block,
    and the others to 'none'.
    Code:
    function showBlock(e){
    	e= window.event || e;
    	var who= e.target || e.srcElement;
    	var val= who.options[who.selectedIndex].value;
    	var show= document.getElementById(val);
    	var A= document.getElementsByTagName('div');
    	var L= A.length, tem;
    	for(var i= 0; i<L;i++){
    		tem= A[i];
    		if(/\bshowBlockCss\b/.test(tem.className)){
    			if(tem== show)tem.style.display= 'block';
    			else tem.style.display= 'none';
    		}
    	}
    }
    
    onload= function(){
    	var el= document.getElementByTagName('select')[0];
    	el.onchange= showBlock;
    	// substitute the correct reference for your select element
    }
    Last edited by mrhoo; Jan 24, 2008 at 11:14. Reason: correction

  3. #3
    SitePoint Zealot
    Join Date
    Dec 2007
    Posts
    120
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Code:
    <script type="text/javascript">
    function showHide(id) {
        var elem = document.getElementById(id);
        if (elem.style.display == 'none') elem.style.display = 'block';
        else elem.style.display = 'none';
    }
    </script> 
    
    <a href="#" onclick="showHide('box1')">Box 1</a> |
    <a href="#" onclick="showHide('box2')">Box 2</a> |
    <a href="#" onclick="showHide('box3')">Box 3</a>
    
    <div id="box1" style="display:none; width:200px; height:200px; background:blue; color:#fff;">Box 1</div>
    <div id="box2" style="display:none; width:200px; height:200px; background:red; color:#fff;">Box 2</div>
    <div id="box3" style="display:none; width:200px; height:200px; background:yellow; color:#000;">Box 3</div>

  4. #4
    SitePoint Enthusiast Pure L's Avatar
    Join Date
    Oct 2007
    Posts
    47
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    thanks!

    Thanks for the replies guys.

    MP,
    I like your code but my only complaint is that all divs can be on the page at the same time.

    What I'd like is for their to be only one visible at any one time. (That's what I was accomplishing with my previous "novel-version" of my code, anyway).

    I've been fiddling with your code and trying to get it to only allow one div at a time but am not coming up with anything.

    Any suggestions would be most appreciated!

    Thanks.

  5. #5
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    I know that you want to use the this keyword, but that only relates to the object that was clicked on. We can still use the this keyword to get the link that was clicked on, but more importantly is figuring out the identifier that we want to act on. There is a useful technique for this where we use the fragment identifier of the link itself.

    However, before that we should consider what happens should there be no JavaScript. If that's the case then all of the content sections should be visible, with the menu link taking you down to the appropriate section. When JavaScript is available it can use those fragment identifiers as well to do its own thing.

    The welcome link is very useful in the navigation for scripting, but we won't want to see it so we'll hide it from being displayed. The good news is that this hidden class is also going to be used on the content sections too.

    Code CSS:
    .hidden {
        display: none;
    }

    Code HTML4Strict:
    <ul id="menu">
        <li><a href="#welcome" class="hidden">Welcome</a></li>
        <li><a href="#about">About<a></li>
        <li><a href="#services">Services</a></li>
        ...
    </ul>

    The welcome part has been included above because whenever a link is clicked, we're going to walk through each menu item to turn off or on each related section.

    When JavaScript is available you want to hide all sections except for the first one. It should go without saying that this piece of code needs to be run after the elements are ready to be used, and a very good way to achieve this is to place it in script tags at the bottom of the document.

    We will also want to attach the onclick element to the navigation links at the same time. A toggle function isn't going to be useful, so we'll have separate show and hide functions instead.

    Let's pause for a moment to consider things for a bit.

    When the page starts we are going to hide sections by walking through the menu and use the fragment identifier to hide the sections.

    When the link is clicked we are going to go to a displaySection() function that will walk through the navigation menu, and use the fragment identifier to show and hide the sections.

    There is a lot of duplication there, so let's create a function to convert the link fragment to an identifier, and some functions to show and hide elements.

    Code Javascript:
    function linkFragmentAsId(el) {
        return el.getAttribute('href').split('#')[1];
    }
    function show(id) {
        document.getElementById(id).className = '';
    }
    function hide(id) {
    	document.getElementById(id).className = 'hidden';
    }

    When creating the above functions you have to consider whether you will be passing the show and hide functions an element itself, the identifier of an element. I have chosen to use identifiers in this case to make comparison of them easier later on.

    There is more duplication that occurs when we load the page or click a navigation link, in that we are walking through the navigation menu and deciding what to turn of and on. We can have just the one function called forEachMenuLink() for this and pass it a function to perform on each one. When passing arguments to the function, I'm also going to pass the index number as well, which will become useful later on.

    Code Javascript:
    function forEachMenuLink(fn, args) {
        var menu = document.getElementById('menu');
        var links = menu.getElementsByTagName('a');
        var i;
        for (i = 0; i < links.length; i++) {
    	    fn(links[i], args, i);
    	}
    }


    Now we can do several things with with menu links. We can use them when the link is clicked, which will run the displaySection function

    You may notice that I'm using descriptive function names. They may appear to be a little long at first, but they do make the code a lot easier to understand.

    Code Javascript:
    function displaySection() {
        var section = linkFragmentAsId(this);
    	forEachMenuLink(displayIfClicked, section);
    }
    function displayIfClicked(link, section) {
    	fragmentId = linkFragmentAsId(link);
    	if (fragmentId === section) {
    		show(fragmentId);
    	} else {
    		hide(fragmentId);
    	}
    }

    And we can attach the onclick event to each link, and also simulate the first link (welcome) being clicked when the page starts.

    If you're wondering why we don't just attach events in HTML with the onclick attribute, consider why you don't use inline CSS on HTML pages. Keeping the scripted behaviour separate from the content is just as important as separating the presentation from the content.

    Code Javascript:
    function attachOnclickEvent(link, active, index) {
        link.onclick = displaySection;
    	if (index === active) {
    		link.onclick();
    	}
    }
    forEachMenuLink(attachOnclickEvent, 0);
    Last edited by paul_wilkins; Jan 24, 2008 at 17:02.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  6. #6
    SitePoint Evangelist
    Join Date
    Jul 2007
    Posts
    345
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Nicely done pmw57.

    A very quick and dirty version:

    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Block Switcher</title>
    <script type="text/javascript">
    function show(block) {
    	var blocks = ['bob', 'dan', 'mol'];
    	for (var i = 0; i < blocks.length; i++) {
    		document.getElementById(blocks[i]).style.display = "none";
    	}
    	document.getElementById(block).style.display = "";
    }
    </script>
    
    </head>
    
    <body>
    <h1>Block Switcher</h1>
    
    <p><a href="#" onclick="show('bob');">Bob</a> | <a href="#" onclick="show('dan');">Dan</a> | <a href="#" onclick="show('mol');">Mol</a></p>
    
    <p id="bob">Info 1 - Bob</p>
    <p id="dan">Info 2 - Dan</p>
    <p id="mol">Info 3 - Mol</p>
    
    </body>
    </html>
    It depends what you want, what it's for and if it's likely to be reused - which it probably is.

  7. #7
    SitePoint Guru
    Join Date
    Sep 2006
    Posts
    731
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Pure L View Post
    I'm basically just changing the style of 6 divs to "display:block" or "display:none" using some simple javascript.

    I'm willing to bet I'm doing it the hard way, however.

    Perhaps using "this" somehow?

    Any help is much appreciated. Thanks.
    Here's a solution using this:
    Code:
    <script type='text/javascript'>
    
    function showJustOne()
    {
     this.elemIds=[];
     
     for(var i=0; i<arguments.length; i++)
      this.elemIds[i]=arguments[i];
      
     this.only=function(id)
     {
      for(var i=0, elem; i<this.elemIds.length; i++)
       if( (elem=document.getElementById( this.elemIds[i] ))!=null )
        elem.style.display=(this.elemIds[i]==id?'':'none');
        
      return false;  
     } 
    }
    
    var show = new showJustOne("aboutDiv","servicesDiv","pricingDiv","testimonialsDiv","makeAnAppointmentDiv");
    
    </script>
    
    <a href='#' onclick='return show.only("aboutDiv")'>About</a>
    Tab-indentation is a crime against humanity.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •