# javascript menu not working in Firefox



## tkjensen (Jul 11, 2008)

I have placed a javascript menu with categories and drop down lists for those categories on a new website. It works perfectly in IE but in Firefox it just places a red border around the category links. I don't have firefox myself, but the client I am building the site for does. Would this have to do with permissions in their firefox browser or could it be a universal problem? She tells me she has seen javascripts in her browser before (but then she could be mistaken because of her level of experience). Thank you for your help!


----------



## Oberon2000 (Jul 2, 2008)

Is there anyway to get the javascript online? It would be a little bit easier to debug then. Also, did you check the javascript settings within firefox?


Firefox: "Tools -> Options -> Content -> Enable JavaScript"

Another option, if your client is running Windows, is to install the "IE Tab" plugin for firefox (http://ietab.mozdev.org). It's not perfect but will handle most websites that require IE only.


----------



## jamiemac2005 (Jul 5, 2007)

Hey, the problem is probably cross-browser compliance within your script. It's a bugger, but you have to code the script to know what to use for either browser....

I usually suggest this site when someone's having problems with cross-browser compliance/compatibility... http://www.reloco.com.ar/mozilla/compat.html

Because it has most of the compatibility problems highlighted...

If you can't find something in there which is in your script then post your code and i'm sure someone will find something... (or link to the site so we can actually see what's going on)....

Cheers,
Jamey


----------



## tkjensen (Jul 11, 2008)

ok, I did have my client check her settings in firefox and they appeared ok. We even changed a few settings to allow more things but to no avail.

The script is live at http://www.wrightwoodchiropracticcare.com though the creation of the page is still in progress. 

I will suggest she install the IE tab Oberon200 suggested, but this cannot happen until Monday, and unfortunately, would only solve the problem on her machine. While that is better than nothing, of course I would prefer it to be compatible with all browsers.

I visited the site that jamiemac2005 suggested above, but it seems that none of the suggestions on specific code apply since I could not find them in the script itself. I did not write the script, while I do have a background in programming I do not know java well enough to do anything other than fiddle with an existing script to get it to work.

Here's the code (and thanks again for all your help):

<HEAD>

<style type="text/css">
a
{text-decoration: none;}

.title
{position: absolute;
width: 100px;
height: 20px;
left: 5px;
z-index: 10;
font-family: verdana, helvetica, sans-serif;
font-weight: bold;
font-size: 13px;}

.submenu
{position: absolute;
left: 15px;
width: 115px;
border: 0px solid black;
background-color: green;
layer-background-color: yellow;
font-family: verdana, helvetica, sans-serif;
font-size: 11px;
visibility: hidden;}
</style>

<SCRIPT LANGUAGE="JavaScript">
<!-- Original: Fredrik Fridsten ([email protected]) -->
<!-- Web Site: http://hem.passagen.se/dred -->

<!-- This script and many more are available free online at -->
<!-- The JavaScript Source!! http://javascript.internet.com -->

<!-- Begin

// ADDITIONAL NOTES
// The input variables to the toggle function are the number of the submenu to open/close,
// starting with 0, and the number of pixels to move the objects below.
// For example toggle(1,60) opens/closes the second submenu and moves the objects below 60 pixels.

var nom = 4; // Number of menus
var usePictures = 1; // use pictures? 1 = yes, 0 = no

var ttls = new Array(); // An array for the title objects
var subs = new Array(); // An array for the submenu objects
var lastn;
var lastmove;

if (document.layers) {
visible = 'show';
hidden = 'hide';
}
else
if (document.all) {
visible = 'visible';
hidden = 'hidden';
}
for (var i = 1; i <= nom; i++) {
ttls_ = ('title' + i);
subs = ('submenu' +i);
}
function picopen {
title = ('title' + n);
pic = ('pic' + n);
if (document.layers) {
document.layers[title].document.images[pic].src = "opened.gif";
}
else if (document.all) {
document.all(pic).src = "opened.gif";
}
}
function picclose {
title = ('title' + n);
pic = ('pic' + n);
if (document.layers) {
document.layers[title].document.images[pic].src = "closed.gif";
}
else if (document.all) {
document.all(pic).src = "closed.gif";
}
}
lastn = (nom + 1);
lastmove = 0;
function lasttoggle(n,move) {
if (n <= nom) {
menu = ('submenu' + n);
if (document.layers) {
submenu = document.layers[menu];
}
else if (document.all) {
submenu = document.all(menu).style;
}
if (submenu.visibility == visible) {
submenu.visibility = hidden;
picclose; // Remove this if you don't use pictures
for (var i = (n+1); i <= nom; i++) {
if (document.layers) {
document.layers[ttls].top -= move;
document.layers[subs].top -= move;
}
else if (document.all) {
document.all(ttls).style.pixelTop -= move;
document.all(subs).style.pixelTop -= move;
}
}
}
}
}
function toggle(n,move) {
menu = ('submenu' + n);
if (document.layers) {
submenu = document.layers[menu];
}
else if (document.all) {
submenu = document.all(menu).style;
}
if (submenu.visibility == visible) {
submenu.visibility = hidden;
if (usePictures) picclose;
for (var i = (n+1); i <= nom; i++) {
if (document.layers) {
document.layers[ttls].top -= move;
document.layers[subs].top -= move;
}
else if (document.all) {
document.all(ttls).style.pixelTop -= move;
document.all(subs).style.pixelTop -= move;
}
}
}
else {
submenu.visibility = visible;
if (usePictures) picopen;
if (lastn != n) {
lasttoggle(lastn,lastmove);
}
for (var i = (n+1); i <= nom; i++) {
if (document.layers) {
document.layers[ttls].top += move;
document.layers[subs].top += move;
}
if (document.all) {
document.all(ttls).style.pixelTop += move;
document.all(subs).style.pixelTop += move;
}
}
}
lastn = n;
lastmove = move;
}
// End -->
</script>
</HEAD>
<BODY background="bggreenLside.jpg" BGCOLOR="#44A361" TEXT="white" ALINK="white" LINK="white" VLINK="white" marginheight="0" marginwidth="0" bottommargin="0" topmargin="0" leftmargin="0">


<p><br clear=all>

<table border=0><tr><td>
<div class="title" id="title1" style="top: 30px"> 
<a href="#" onclick="javascript: toggle(1,30); return false"><img name="pic1" src="http://javascript.internet.com/img/category-menus/closed.gif" border="0">Category 1</a>
</div>

<div class="submenu" id="submenu1" style="top: 50px">
<a href="page01.html" target="right">Item # 1</a></a><br>
<a href="page02.html" target="right">Item # 2</a>
</div>

<div class="title" id="title2" style="top: 60px"> 
<a href="#" onclick="javascript: toggle(2,50); return false"><img name="pic2" src="http://javascript.internet.com/img/category-menus/closed.gif" border="0">Category 2</a>
</div>

<div class="submenu" id="submenu2" style="top: 80px">
<a href="page03.html" target="right">Item # 3</a><br>
<a href="page04.html" target="right">Item # 4</a><br>
<a href="page05.html" target="right">Item # 5</a><br>
<a href="page06.html" target="right">Item # 6</a>
</div>

<div class="title" id="title3" style="top: 90px"> 
<a href="#" onclick="javascript: toggle(3,40); return false"><img name="pic3" src="http://javascript.internet.com/img/category-menus/closed.gif" border="0">Category 3</a>
</div>

<div class="submenu" id="submenu3" style="top: 110px">
<a href="page07.html" target="right">Item # 7</a><br>
<a href="page08.html" target="right">Item # 8</a><br>
<a href="page09.html" target="right">Item # 9</a>
</div>

<div class="title" id="title4" style="top: 120px"> 
<a href="#" onclick="javascript: toggle(4,50); return false"><img name="pic4" src="http://javascript.internet.com/img/category-menus/closed.gif" border="0">Category 4</a>
</div>

<div class="submenu" id="submenu4" style="top: 140px">
<a href="page10.html" target="right">Item # 10</a><br>
<a href="page11.html" target="right">Item # 11</a><br>
<a href="page12.html" target="right">Item # 12</a><br>
<a href="page13.html" target="right">Item # 13</a>
</div>

</td></tr>
</table>
<p> <p> <p> <p>

</BODY>_


----------



## jamiemac2005 (Jul 5, 2007)

Hey again,
i've been butchering your code for the past 5-10 mins to get the script working in FF... Then tried to get it to work in both, but i need some input on a piece of code you use:


```
if (document.layers) {
...
}
else if (document.all) {
...
}
```
Basically, (because i can't remeber nor do i have the browsers to check) this seems like a small amount of browser-compatibility check? so which browsers does it differentiate between?

Because FF understands the document.all object but not the code which is used within the code blocks...

Now to my "fix"es, I have disabled the use of IE on my PC so have only had IE-Tab to differentiate between the behaviour within the two browsers, and as i saved your homepage to my local pc to modify it (in a way in which IE does not like)... I cannot test the full functionality of the page in IE (but from what i've done i see that the functionality in IE has changed slightly[The old menu does not collapse when a new one is opened] but you'll have to check that)...

I replaced the use of document.all with document.getElementById...
Then butchered your code some more... You'll have to look at the result (which i've attached), to see the full extent of what i've done... it works perfectly in FF, but not fully in IE (you'll have to check&change that)... I've commented most of my changes but as i said "butchered"...

Post back with more so i can help more etc.

Cheers,
Jamey


----------



## jamiemac2005 (Jul 5, 2007)

Hey again,

I've been butchering some more code this morning in order to get the page working in both FF and IE

And it does

So now i can explain exactly what i've done and upload the new category-menus.htm file (for you to see what i've done again)... I've commented the final file aswell so you can see what i've done

Okay, i'll start at the top of the script:


```
[b]var visible, hidden;[/b]

//This piece of code differentiates between IE and Netscape based browsers(e.g. firefox)
[b]if (navigator.appName=="Microsoft Internet Explorer"){[/b]
	if (document.layers) {
		visible = 'show';
		hidden = 'hide';
	} else if (document.all) {
		visible = 'visible';
		hidden = 'hidden';
	}
[b]}else{
	//Assume Netscape based (or navigator.appName=='Netscape')
	visible='visible';
	hidden = 'hidden';
}[/b]
```
Okay here there are 2 changes:

The first "var visible, hidden"... I added these here because they have to be global variables for FF to pick them up later on in the script(where they're used)...

Also i used the code "if (navigator.appName=="Microsoft Internet Explorer"){" to differentiate between IE and FF... which works fine throughout the code... in this top case visible and hidden would have been set by the stuff within document.all (which was correct anyway[apart from the variable scope])...

Now for the picopen and picclose functions:


```
function picopen(n) {
	title = ('title' + n);
	pic = ('pic' + n);
	[b]//using the same code as above to differentiate between IE/Netscape
	if (navigator.appName=="Microsoft Internet Explorer"){[/b]
		if (document.layers) {
			document.layers[title].document.images[pic].src = "opened.gif";
		} else if (document.all) {
			document.all(pic).src = "opened.gif";
		}
	[b]} else {
		//if FF then use the document.getElementById() method.
		document.getElementById(pic).src = "opened.gif";
	}[/b]
}
```
As above i differentiated between IE and FF...
Then i used the document.getElementById() method to get the pic object

I also had to add 

```
<img name="pic1" [b]id="pic1"[/b] ...
```
the id to the images in the HTML part of your code so that getElementById recognised them...

I then did the same for the picclose function (so theres no point in going over it again)



Finally, for the toggle functions(i did the same in both so don't see a point in explaining it twice):


```
function lasttoggle(n,move) {
	if (n <= nom) {
		menu = ('submenu' + n);
		[b]//added this code because submenu is made local to the if statements if it's not here
		var submenu;[/b]
		//using the same code as above to differentiate between browsers
		[b]if (navigator.appName=="Microsoft Internet Explorer"){[/b]
			if (document.layers) {
				submenu = document.layers[menu];
			} else if (document.all) {
				submenu = document.all(menu).style;
			}
		[b]} else {
			//Assume FF
			//use the document.getElementById object
			submenu = document.getElementById(menu).style;
		}[/b]
		if (submenu.visibility == visible) {
			submenu.visibility = hidden;
			[b]//added the code from below to the next line to ensure consistency
			if (usePictures)[/b] picclose(n); // Remove this if you don't use pictures
			for (var i = (n+1); i <= nom; i++) {
				[b]//same code as before to differentiate between browsers
				if (navigator.appName=="Microsoft Internet Explorer"){[/b]
					if (document.layers) {
						document.layers[ttls[i]].top -= move;
						document.layers[subs[i]].top -= move;
					} else if (document.all) {
						document.all(ttls[i]).style.pixelTop -= move;
						document.all(subs[i]).style.pixelTop -= move;
					}
				[b]} else {
					//FF is the browser
					//use document.getElementById(ttls/subs)
					//The .top property in css contains a "px" in it so js assumes it's a string hence you cannot just negate it you must first parse the value of .top
					var oldTop = document.getElementById(ttls[i]).style.top;//gets the old .top property
					var parsedTop = parseInt(oldTop);//converts it from string to integer and removes the "px"
					var newTop = parsedTop-move;//negates move
					document.getElementById(ttls[i]).style.top = newTop+"px";//resets it and adds the "px"
					//do the same for subs
					var oldTop = document.getElementById(subs[i]).style.top;//gets the old .top property
					var parsedTop = parseInt(oldTop);//converts it from string to integer and removes the "px"
					var newTop = parsedTop-move;//negates move
					document.getElementById(subs[i]).style.top = newTop+"px";//resets it and adds the "px"
				}[/b]
				
			}
		}
	}
}
```
Okay, i had to sort out the variable scope of submenu (by setting it as local to the function rather than the if statements...

Then i used the same code to differentiate between browsers, and set submenu as the submenu object using the document.getElementById() method.

Finally i added the code:

```
var oldTop = document.getElementById(ttls[i]).style.top;//gets the old .top property
var parsedTop = parseInt(oldTop);//converts it from string to integer and removes the "px"
var newTop = parsedTop-move;//negates move
document.getElementById(ttls[i]).style.top = newTop+"px";//resets it and adds the "px"
```
Because the css ".top" property has the characters "px" in it...
and that makes js think it's a string
and you can't negate from a string...
so i used the parseInt() method to parse the integer from the value of .top

then negated move from it
then re-set it



I hope this is all understandable, as i said i've attached the new file so you can see the full extent of the changes. (had to zip it to upload it on this site)

If you need any more help on it then please post back


Cheers,
Jamey


----------



## tkjensen (Jul 11, 2008)

Hey Jamey,

Thanks for all your work!! I think I have made sense in my head of what you have done but won't pretend I could have figured it out myself. 

Once I removed the absolute references to objects it works fine in my IE, I don't have firefox (and dread adding more programs to my 4yr old machine - (is FF relatively small and problem free?)) so I'm trusting on that and hope to have a happy client on Monday, thanks to you 

This forum is invaluable - to reach out in the ethers of cyberspace and have needs answered by cyberangels/friends.

Once I hear from my client I will post the news.

You're the best! 

Terese


----------



## jamiemac2005 (Jul 5, 2007)

Hey again,

Thats k, i havent used js in a major way recently so it was fun hah.

Hope all goes well.

Cheers,
Jamey


----------



## tkjensen (Jul 11, 2008)

hey again 

I spoke with my client today and its working great! I was hoping you had fun doing it but that does not diminish my gratitude!ray:

thanks again! T


----------



## jamiemac2005 (Jul 5, 2007)

Glad to hear it works okay... =]

Cheers,
Jamey


----------



## fridsten (Oct 21, 2008)

Hi everybody! I stumbled upon this (old) thread when doing a Google search for my own last name. (Pathetic, right?)

I wrote that menu script back in 2000 and updated it in 2002 to get it to work with Javascript DOM2. You can get the updated version here: http://www.fridsten.se/script/

/Fredrik Fridsten


----------

