Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Infinite recursion problem

Status
Not open for further replies.

equazcion

Technical User
Mar 14, 2004
11
US
I just started seeking programming help in forums and I haven't quite gotten the knack for explaining these problems without War-and-Peace-length posts, so please excuse that. I'm really stuck here though so if you can find it in your heart to bear with me I'd be most gracious.

I'm outputting a list of records using PHP/mySQL. The records are outputted into DIVs. For each record, I have a group of "tabs" displayed for navigating through the different pages of data in the record. In other words, there is a separate group of tabs for each record.

Each tab is just a DIV, not an image. I want them to have the standard tab-like behavior: onmouseover effects, as well as an onclick effect that keeps the current tab a different color than the others, so the user knows which section they're currently looking at.

I'm using javascript to loop through all the tabs in the page onLoad and apply all the onmouseover and onclick handlers. The problem is, one of the things I need to happen onclick is that all other tabs in that record change as well. For instance if a user is looking at the "info" tab and clicks the "data" tab, the data tab's event handlers should be set to nothing (so that a user can't click the tab they're currently looking at), while also re-applying the "info" tab's event handlers, so that the user will be able to switch back there later.

As you can see below, the only method I can see for doing this is to set the tabs' onclick events to a function, all of which happens onclick of one of the tabs - and that causes a "too much recursion" javascript error. I think that rather than just assigning the function to the onclick event, it is also evaluating the function while it gets assigned, which causes an infinite loop. I can't figure out why it's doing that or how to stop it.

Here's my onload() function. Notice the last line of the third for() loop, when onclick gets set to the very function we're currently in. That's where the javascript error always points to. Again, this might seem like it would cause an infinite loop, but the function is only supposed to be getting ASSIGNED to the onclick event, and not actually getting called then and there.

Can anyone clue me in? Thanks to anyone who can offer even the tiniest clue. I'm really stumped.

PS - I don't think this has anything to do with it but in case you're wondering, I'm using a getElementsByClassName function by Jonathan Snook:

function onload(){
var tabBars = getElementsByClassName(document, '*', 'tab-bar');
for (x=0; x < tabBars.length; x++){
var id = tabBars[x].id;
var tabs = getElementsByClassName(document.getElementById(id), 'div', 'tab');
for (i=0; i < tabs.length; i++){
var class = tabs.className;
tabs.onmouseover = function(){this.className = class + ' over';}
tabs.onmouseout = function(){this.className = class;}
tabs.onclick = function clicked(){
for (c=0; c < tabs.length; c++){
tabs[c].className = class;
tabs[c].onmouseover = function(){this.className = class + ' over';}
tabs[c].onmouseout = function(){this.className = class;}
if (tabs[c].id != this.id) {tabs[c].onclick = clicked();}
}
this.className = class + ' on';
this.onmouseover = '';
this.onmouseout = '';
this.onclick = '';
}
}
}
}
 
PS - I don't think this has anything to do with it but in case you're wondering, I'm using a getElementsByClassName function by Jonathan Snook

Actually, that function is the exact reason why you have a problem. There only recursion in your function would be calls to the getElementsByClassName function.

Instead, use the getElementsByTagName and loop through your elements, checking the className on each loop until you get to the className you need.

[monkey][snake] <.
 
Thanks for replying -

I don't think getElementsByClassName is the problem though, because if I comment out the line I pointed out in my original post, where the function (clicked()) gets assigned to the onclick event, there are no javascript errors anymore. Besides The getElementsByClassName function doesn't get called during any event except the original page load, and I don't get any errors during onload, only onclick.

I could be wrong though - maybe someone else can confirm this. Nevertheless I really appreciate the reply :)
 
It gets called multiple times:

Code:
    [!]var tabBars = getElementsByClassName(document, '*', 'tab-bar');  Here[/!] 
    for (x=0; x < tabBars.length; x++){
        var id = tabBars[x].id;
        [!]var tabs = getElementsByClassName(document.getElementById(id), 'div', 'tab'); Many times here[/!]
        for (i=0; i < tabs.length; i++){
            var class = tabs[i].className;
            tabs[i].onmouseover = function(){this.className = class + ' over';}
            tabs[i].onmouseout = function(){this.className = class;}
            tabs[i].onclick = function clicked(){    
                for (c=0; c < tabs.length; c++){
                    tabs[c].className = class;
                    tabs[c].onmouseover = function(){this.className = class + ' over';}
                    tabs[c].onmouseout = function(){this.className = class;}
                    if (tabs[c].id != this.id) {tabs[c].onclick = clicked();}
                }
                this.className = class + ' on';
                this.onmouseover = '';
                this.onmouseout = '';
                this.onclick = '';
            }
        }
    }

Based on what I see, I'd just create all those event handler functions externally and use innerHTML to call those functions (As well as the getElementsByTagName).

[monkey][snake] <.
 
I'm not sure how calling getElementsByClassName multiple times would cause a recursion error. It's just a function that basically does what you're saying I should do manually, getting elements by tag name and looping through them to get their class name. It doesn't seem like re-writing it myself make any difference.

Your suggestion to place the event handlers outside the onload function seemed on the money, but unfortunately I tried that already and found that it still didn't allow me to avoid having a function call itself at some point. Of course it shouldn't actually be calling itself, only assigning itself as an event handler. But the point is, the same problem is always there no matter how much I try to separate everything.

Again I thank you for the response, it's much appreciated :)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top