SitePoint Sponsor

User Tag List

Results 1 to 3 of 3
  1. #1
    SitePoint Member
    Join Date
    Jan 2008
    Posts
    2
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Simple javascript/css tabs, I just need a hand debugging the js...

    I've done the best I can to figure out why this script doesn't work. I'm relatively new to javascript though, so that's probably the issue...
    Anyway, It's a short script and I'm just going to post the entire thing here, I've included detailed comments on how things are *supposed* to work, so hopefully someone will be able to see where I went wrong.

    The objective of this script is to display the contents of a single file in multiple tabs on a page. The original script underneath mine does this perfectly.
    However, I need to be able to have several independent tab bars on a single page. The original script works for that, but only one tab can be opened at any time on the entire page.

    I realize that there are probably already instructions on how to do this somewhere in this forum or another. The reason i'm posting this is that I have been trying forever to avoid learning javascript. I just copy public code and use it in it's original form. Recently I have tried to learn JS, but haven't had much success even from tutorials. I used to be fairly competent with C++, so I know the in's and out's of OOP. I think the best way for me to become proficient with JS is to just do it, and get help debugging my code when necessary. I think this will give me a greater overall understanding of the DOM.

    Anyway, back to my tabs...

    Tabs are arranged in the html like this:
    HTML Code:
    <dl> - this is a list of tabs or a tab bar
        <dt> - this is the first tab title </dt>
        <dd> - this is the data for the preceeding tab title</dd>
        <dt> - this is a second tab title </dt>
        <dd> - this is the data for the preceeding tab title</dd>
        <dt> - this is a third tab title </dt>
        <dd> - this is the data for the preceeding tab title</dd>
        <dt> - this is a fourth tab title </dt>
        <dd> - this is the data for the preceeding tab title</dd>
    </dl>
    The html for the tabs was built into the original script I used, and I felt no need to change it. I do have one question though - These don't look like standard html tags to me. Is it legal to create tags with original names. could I get away with something like this?
    HTML Code:
    <tablist> - this is a list of tabs or a tab bar
        <tabtitle> - this is the first tab title </dt>
        <tabdata> - this is the data for the preceeding tab title</dd>
        <tabtitle> - this is a second tab title </dt>
        <tabdata> - this is the data for the preceeding tab title</dd>
        <tabtitle> - this is a third tab title </dt>
        <tabdata> - this is the data for the preceeding tab title</dd>
        <tabtitle> - this is a fourth tab title </dt>
        <tabdata> - this is the data for the preceeding tab title</dd>
    </tablist>
    If that kind of flexibility is allowed in html or xhtml, then I could make my JS code a lot more readable to myself (and others).

    I'm not going to post the CSS for the tabs - mostly because it's so flexible... There's no right or wrong way to use this code, I may end up using this to create explorer-style menus or customizable webpages. All of that is done with css, which isn't relative to my JS code...

    Here is my attempt at creating a script that should allow each different tab bar to act independently:
    Code:
    //Run startup functions after the page loads
    window.onload = windowLoad;
    
    //create a global variable to store a list of tab bars
    var tabBars;
    
    //startup functions
    function windowLoad() {
    	setTabBars;
    	setBehavior;
    }
    
    //load the global variable tabBars with the individual tab bars and tabs
    function setTabBars() {
    	tabBars = document.getElementsByTagName('dl'); //loads all the tab bars into the variable
    	for ( b = 0 ; b < tabBars.length ; b++) { //for each tab bar...
    		dd = tabBars[b].nextChild;
    		t = 0;
    		while (dd) { //...store a list of the tabs it contains
    			if (dd.tagName = 'dt')
    			tabBars[b].tabs[t] = dd;
    			t++
    			dd = dd.nextSibling;
    		}
    	}
    }
    
    //specify how the user interacts with the tabs
    function setBehavior() {
    	for (b = 0; b < tabBars.length; b++) {
    		for (t = 0; t < tabBars[b].tabs.length; t++) {
    			//each tab should, when clicked, pass a reference to itself, and it's container tab bar,
    			//onto the activateTab function
    			tabBars[b].tabs[t].onclick = activateTab(tabBars[b], tabBars[b].tabs[t]);
    		}
    	}
    }
    
    //specify what the tabs are supposed to do when clicked
    function activateTab(tabBar,tab){
    	for (i = 0; i < tabBar.length; i++) { //make all the tabs in the current tab bar be closed
    		tabBar[i].className = "";
    		dd = tabBar[i].nextSibling;
    		dd.className = "";
    	}
    	if (!tab.className) { //check if the clicked tab is already open, if it's not, then open it
    		tab.className = "current";
    		dd = tab.nextSibling;
    		dd.className = "current";
    	} else { //if the current tab is already open, then close it
    		tab.className = "";
    		dd = tab.nextSibling;
    		dd.className = "";
    
    	}
    }
    In case it helps - here is a copy of the original *working* script:
    Code:
    //below is a slightly modified version of the original script that is the inspiration for my work above
    //all credits go to A List Apart, though I do not know the original author.
    //this script works perfectly
    //-------------------------------------------------------
    /*
     window.onload = setBehavior;
     
     function setBehavior(){
    	tabs = document.getElementsByTagName('dt');
    	for (t=0;t < tabs.length; t++ ){
    		tabs[t].onclick = activateTab;
    	}
    };
    
    function activateTab(){
    	if (this.className != "current") {
    		tabs = document.getElementsByTagName('dt');
    		for (t = 0; t < tabs.length; t++) {
    			if (tabs[t].className == 'current') {
    				tabs[t].className = "";
    			}
    		}
    		page = document.getElementsByTagName('dd');
    		for (t = 0; t < page.length; t++) {
    			if (page[t].className == 'current') {
    				page[t].className = "";
    			}
    		}
    		this.className = "current";
    		dd = this.nextSibling;
    		if (dd.nodeType != 1) {
    			dd = dd.nextSibling;
    		}
    		dd.className = "current";
    	}
    	else {
    		this.className = "";
    		dd = this.nextSibling;
    		if (dd.nodeType != 1) {
    			dd = dd.nextSibling;
    		}
    		dd.className = "";
    	}		
    };
    */

  2. #2
    SitePoint Wizard
    Join Date
    Nov 2004
    Location
    Nelson BC
    Posts
    2,310
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    A couple of problems I can see without really debugging anything:
    Code:
    //startup functions
    function windowLoad() {
    	setTabBars;
    	setBehavior;
    }
    This won't work. It needs to be
    Code:
    //startup functions
    function windowLoad() {
    	setTabBars();
    	setBehavior();
    }
    Also, the closures are not being created properly here:
    Code:
    tabBars[b].tabs[t].onclick = activateTab(tabBars[b], tabBars[b].tabs[t]);
    likely what will happen is the last tab created will be activated regardless of what was clicked.

    Try:
    Code:
    setTabOnclick(tabBars[b], tabBars[b].tabs[t]);
    
    
    // this function goes outside other functions
    function setTabOnclick(tabBar, tab) {
      tab.onclick = function () { activateTab(tabBar, tab); };
    }
    Last edited by jimfraser; Jan 29, 2008 at 09:57. Reason: glaring error in onclick function =)

  3. #3
    SitePoint Member
    Join Date
    Jan 2008
    Posts
    2
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for the help. I'll try to get it working later today.


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
  •