Jump to content

Creating a navigation tab list, but it crashes browser


Coh3n

Recommended Posts

Hi! I recently started creating my own website out of pure interest, teaching myself, so I apologise in advance for any "weird" code I could post. I've been trying to create a navigation list on my hompage (seen here -- do not click the tabs unless you want to see your browser crash). I know I can simply have a different HTML page for each "tab" (i.e. Home, About Me, etc.), but I really hate having repeated code, and I figure there has to be an alternative. This is what I've come up with so far:

function onClickNavTab(numOfTabs){	var i;		// loop through each tab, finding which one is active, then disabling it and breaking out of the loop	for (i = 1; i = numOfTabs; i++)	{		var navTab = document.getElementById("navTab_"+i);		console.debug("loop #"+i);				// if the active tab is found, set it inactive (or no class name at all)		if (navTab.getAttribute("class") == "active")		{			console.debug("found active navigation tab");			navTab.setAttribute("class", "");			break;		}	}			this.setAttribute("class", "active"); // set the tab that was clicked to active, so it becomes highlighted}

And I'm using it like this:

   	 <div id="header">			<div id="title"><u>CA</u> | Cohen Adair </div>						<div id="nav">				<ul>					<li><a id="navTab_1" onClick="onClickNavTab(5)" class="active" href="#">Home</a></li>					<li><a id="navTab_2" onClick="onClickNavTab(5)" href="#">About Me</a></li>					<li><a id="navTab_3" onClick="onClickNavTab(5)" href="#">Projects</a></li>					<li><a id="navTab_4" onClick="onClickNavTab(5)" href="#">Blogs</a></li>					<li><a id="navTab_5" onClick="onClickNavTab(5)" href="#">Articles</a></li>				</ul>			</div>						<img src="img/pr_sunset.png" alt="pr_sunset.png" class="cover" />		</div>

And the relevant CSS code:

/***************************************************************************** The properties that setup the navigation list at the top right of the* homepage.****************************************************************************/#nav {	position: absolute;	left: 50%;	top: 28px;	margin-left: -25px;} /* Displays the list across the page */#nav ul li {	display: inline;	font-size: 19px;	} #nav ul li a {	padding: 5px 13px 5px 13px; /* Top, Right, Bottom, Left */	text-decoration: none;	color: black;	border-top-left-radius: 4px;		border-top-right-radius: 4px;	border-bottom-left-radius: 4px;	border-bottom-right-radius: 4px;} #nav ul li a:hover, #nav ul li a.active {	background-image: url(img/bg_light.png);	border-top: 1px solid black;	}

I'm still getting used to Java syntax, and don't have a lot of background in object oriented programming, but you should be able to understand what I'm tring to do from my comments. The javascript function onClickNavTab() is supposed to just "deactivate" the current tab and "activate" the clicked tab. Problem is, when I click another tab, my Firefox crashes... every time. Thanks in advance,Cohen E: Also, if anyone else uses Eclipse, I was wondering if there was a way for it to show me "function is not defined" errors. It shows me syntax errors, but runtime errors I guess they would be don't show up until I try the code in my browser.

Edited by Coh3n
Link to comment
Share on other sites

This: for (i = 1; i = numOfTabs; i++) should be this: for (i = 1; i <= numOfTabs; i++)
Wow, funny how something so simple can cause such a big problem. Thanks for the fix! Question though, why did it cause the browser to crash? The way I had it, wouldn't the loop just execute twice? When i = 1 and when i = numOfTabs, or does the i++ screw that up? Also, now that it doesn't crash, it gives a "this.setAttribute() is not a function" error. Shouldn't "this" be the element object of what is being clicked? Edited by Coh3n
Link to comment
Share on other sites

It was an infinite loop, it kept switching the value of i between 2 values but there wasn't a condition that told it when to stop. The condition that should have told it when to stop instead just set the value of i, so that expression never evaluated to false and the loop never stopped.

Also, now that it doesn't crash, it gives a "this.setAttribute() is not a function" error. Shouldn't "this" be the element object of what is being clicked?
Not inside that function. In the actual event handling code this will be set to the element that the event is happening for, that code is this part: <li><a id="navTab_5" onClick="onClickNavTab(5)"... Inside the code in that onclick attribute, which is the actual event handling code, this is set to the element that was clicked on. When you call the function it doesn't run it in the same scope by default, inside the function this will be set to the window object. If you want a reference to the element that was clicked on then you either need to pass this to your function, or there are other ways to call the function so that it runs in a certain scope, e.g.: <li><a id="navTab_5" onClick="onClickNavTab.call(this, 5)"... That will run the function in the scope of this and pass the value 5 to it.
Link to comment
Share on other sites

It was an infinite loop, it kept switching the value of i between 2 values but there wasn't a condition that told it when to stop. The condition that should have told it when to stop instead just set the value of i, so that expression never evaluated to false and the loop never stopped.
Oh okay I understand. A for loop in Java works a little different than what I'm used to.
Not inside that function. In the actual event handling code this will be set to the element that the event is happening for, that code is this part: <li><a id="navTab_5" onClick="onClickNavTab(5)"... Inside the code in that onclick attribute, which is the actual event handling code, this is set to the element that was clicked on. When you call the function it doesn't run it in the same scope by default, inside the function this will be set to the window object. If you want a reference to the element that was clicked on then you either need to pass this to your function, or there are other ways to call the function so that it runs in a certain scope, e.g.: <li><a id="navTab_5" onClick="onClickNavTab.call(this, 5)"... That will run the function in the scope of this and pass the value 5 to it.
Yeah, after I researched it a little more, I found that was the case. I now pass an "obj" parameter to the function, which got everything working like I wanted. Thanks a lot for the help. Do you guys have some sort of "prefix" system in place where I can tag this thread as "resolved"? It's useful for threads that no longer need attention. Edited by Coh3n
Link to comment
Share on other sites

Oh okay I understand. A for loop in Java works a little different than what I'm used to.
In works the same in other languages that I've studied. The for statement has 3 parts: the initializer, the exit condition, and the iterator. It will execute the initializing statements one time at the start, evaluate the exit condition, run the loop if the exit condition isn't false, and after the loop run the iterator. Your exit condition was an assignment statement: i = numOfTabs; So when it was determining whether to exit the loop it would execute that statement, which assigns a static value to i, evaluate i which would not be false, and since it's not false it would continue the loop. It only exits the loop if that statement evaluates to false. With this instead: for (i = 1; i <= numOfTabs; i++) It's going to exit the loop when i is greater than numOfTabs, so assuming that i and numOfTabs don't get modified inside the loop, that loop will eventually exit.
Do you guys have some sort of "prefix" system in place where I can tag this thread as "resolved"? It's useful for threads that no longer need attention.
You can edit the topic subject if you want, but most people just leave it.
Link to comment
Share on other sites

In works the same in other languages that I've studied. The for statement has 3 parts: the initializer, the exit condition, and the iterator. It will execute the initializing statements one time at the start, evaluate the exit condition, run the loop if the exit condition isn't false, and after the loop run the iterator. Your exit condition was an assignment statement: i = numOfTabs; So when it was determining whether to exit the loop it would execute that statement, which assigns a static value to i, evaluate i which would not be false, and since it's not false it would continue the loop. It only exits the loop if that statement evaluates to false. With this instead: for (i = 1; i <= numOfTabs; i++) It's going to exit the loop when i is greater than numOfTabs, so assuming that i and numOfTabs don't get modified inside the loop, that loop will eventually exit.
Makes sense. I've really only done some Pascal programming, which doesn't have an iterator -- it's just always 1 (at least that's all I know). It's done like for i := 0 to 9 dobeginend; So it would just execute the loop 10 times. I was in the same thought process for Java, where it would just execute for when i = 1 until i = numOfTabs. I didn't think about the "i = numOfTabs" being an assignment. Edited by Coh3n
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...