Click to See Complete Forum and Search --> : DHTML Cross-frame menu


Arknath
07-23-2003, 02:48 PM
Hi!

I am having some difficulty with a crossframe menu that I am writing. Everything works fine except I cannot get the Div containing the dropdown menu to stay on the screen when the user tries to mouse to it.

In other words, here is how I have it set up:

I have a two-frame set (_topFrame, _mainFrame)

_topFrame contains:

Imagemap where the areas call a function on a mouseover (displayMenu) and mouseout (removeMenu) event.

_mainFrame contains:

3 absolutely positioned Div tags that are shown when displayMenu is activated and hidden when removeMenu is activated.

Herein lies my problem. When the user tries to move the mouse to the divs that are showing, the mouseout fires and hides the div tags. My first thought is that I am referencing it incorrectly because the user is moving the mouse from one frame to another, therefore the parent document must point to the _mainFrame in order for the reference to work. Here is the code that I have:

_topFrame:

<script language="JavaScript">

function menuDisplay(mnuName){
mnuConcat=mnuName+"Menu";
parent._mainFrame.document.getElementById(mnuConcat).style.display="inline";
}

function menuRemove(mnuName){
mnuConcat=mnuName+"Menu";
if (event.toElement == parent._mainFrame.document.getElementById(mnuConcat)){
parent._mainFrame.document.getElementById(mnuConcat).style.display="inline";
}else{
parent._mainFrame.document.getElementById(mnuConcat).style.display="none";
}
}
</script>

</head>

<body bgcolor="#ffffff">
<div class="title"> <img src="graphics/ff_title.gif" border="0" usemap="#titleNav"/>
<map name="titleNav" id="titleNav">
<area shape="rect" coords="219,104,330,122" onMouseOver="menuDisplay(this.id)" onmouseout="menuRemove(this.id)" name="animal" id="animal">
<area shape="rect" coords="342,104,420,122" onMouseOver="menuDisplay(this.id)" onmouseout="menuRemove(this.id)" name="accessory" id="accessory">
<area shape="rect" coords="432,104,501,122" onMouseOver="menuDisplay(this.id)" onmouseout="menuRemove(this.id)" name="showing" id="showing">
<area shape="rect" coords="513,104,597,122" href="contact.html" target="_mainFrame">
</map>
</div>

_mainFrame:

<div id="body">



<div class="animalMenuDiv" id="animalMenu">
<table class="menuItem" width="111px">
<tr><td>Birds</td></tr>
<tr class="spacer"><td></td></tr>
<tr><td>Hatchlings</td></tr>
<tr class="spacer"><td></td></tr>
<tr><td>Squirrels</td></tr>
<tr class="spacer"><td></td></tr>
<tr><td>Sugar Gliders</td></tr>
</table>
</div>


<div class="accessoryMenuDiv" id="accessoryMenu">
<table class="menuItem" width="78px">
<tr><td>Cages</td></tr>
<tr class="spacer"><td></td></tr>
<tr><td>Feed</td></tr>
<tr class="spacer"><td></td></tr>
<tr><td>Toys</td></tr>
<tr class="spacer"><td></td></tr>
<tr><td>Miscellaneous</td></tr>
</table>
</div>


<div class="showingMenuDiv" id="showingMenu">
<table class="menuItem" width="69px">
<tr><td>January</td></tr>
<tr class="spacer"><td></td></tr>
<tr><td>February</td></tr>
<tr class="spacer"><td></td></tr>
<tr><td>March</td></tr>
<tr class="spacer"><td></td></tr>
<tr><td>April</td></tr>
<tr class="spacer"><td></td></tr>
<tr><td>May</td></tr>
<tr class="spacer"><td></td></tr>
<tr><td>June</td></tr>
<tr class="spacer"><td></td></tr>
<tr><td>July</td></tr>
<tr class="spacer"><td></td></tr>
<tr><td>August</td></tr>
<tr class="spacer"><td></td></tr>
<tr><td>September</td></tr>
<tr class="spacer"><td></td></tr>
<tr><td>October</td></tr>
<tr class="spacer"><td></td></tr>
<tr><td>November</td></tr>
<tr class="spacer"><td></td></tr>
<tr><td>December</td></tr>
</table>
</div>
<!--<P ALIGN="center"><!-- Counter code version 1.0. Do NOT alter this code!http://counter.mycomputer.com --><!--<img alt="Counter"src="http://counter.mycomputer.com/c.count?u=Feathers&c=1" border=0><!-- End of Counter Code --> </P>
</div>

Any ideas?

Exuro
07-23-2003, 07:16 PM
I think you need a delay so that the user has time to get over to the other menu. Try changing your script to something like this:


<script language="JavaScript">
<!--
var mouseOver=0;
var lastId;

function offHover(id) {
mouseOver=0;
lastId=id;
setTimeout('if (!mouseOver) menuRemove(lastId)', 150);
}

function menuDisplay(mnuName){
mouseOver=1;
mnuConcat=mnuName+"Menu";
parent._mainFrame.document.getElementById(mnuConcat).style.display="inline";
}

function menuRemove(mnuName){
mnuConcat=mnuName+"Menu";
if (event.toElement == parent._mainFrame.document.getElementById(mnuConcat)){
parent._mainFrame.document.getElementById(mnuConcat).style.display="inline";
}
else{
parent._mainFrame.document.getElementById(mnuConcat).style.display="none";
}
}
//-->
</script>

The 150 in the setTimeout() is the length of the delay in miliseconds. You can make it longer or shorter if you want. If you use that you will need to change all your onMouseOuts to onmouseout="offHover(this.id)" instead of onmouseout="menuRemove(this.id)". Hope that helps!

Arknath
07-24-2003, 08:53 AM
First, thanks for the response!

Your code has helped out some, in that it got the menu to stay down. However, it won't go away! :) I also get a "object expected" error when moving onto the div. I've moved the JS code to an external file and loaded it into the main.html and title.html files. Here is the code as it stands now...I've done some playing with it, but this is what you suggested and results in the above error.

var mseOver = 0;
var lastId;

function offHover(id){
mseOver=0;
lastId=id;
setTimeout('if (!mseOver) menuRemove(lastId)', 150);
}

function menuDisplay(mnuName){
mnuConcat=mnuName+"Menu";
parent._mainFrame.document.getElementById(mnuConcat).style.display="inline";
}

function menuRemove(mnuName){
mnuConcat=mnuName+"Menu";
if (event.toElement == parent._mainFrame.document.getElementById(mnuConcat)){
parent._mainFrame.document.getElementById(mnuConcat).style.display="inline";
}else{
parent._mainFrame.document.getElementById(mnuConcat).style.display="none";
}
}

The debugger stops on whereever the "parent._mainFrame..." references are. I've played around with that and nothing seems to fix it.

Exuro
07-24-2003, 06:15 PM
Hoi...
Okay, well, I don't really have your pages and it'd have been alot easier if I had a sample to work with... But I fixed it all up based off what you gave me. In the attached text file is the source code for all 3 HTML documents used in this. Copy the source code out for each one and save it in the properly named HTML file. Then try it out an see if it works for you... I think that error you were talking about was being triggered by that "event.toElement"....

Arknath
07-29-2003, 11:31 PM
I am very excited to say that this works perfectly!! However, since I'm trying to teach myself, maybe you could point out exactly what I was doing wrong. It seems that I was referring to the object incorrectly or that maybe I should have set a default value for the comparison variable (lastId='animal').

Am I close?

Also, something that I have come to realize is that, in order to keep the menu functioning throughout the site, I'll have to include the menu "div" tags on each page. This is not good programming practice (as I know you already know) and I'm wondering if you might have a suggestion on how to perform the HTML on all pages without having to load them onto each page. My first thought is to include a .js file that builds the HTML and displays it as necessary.

Am I close? :)

Thank you again for your help, it is much appreciated!!

Exuro
07-30-2003, 12:41 PM
First off. I looked through my code again and I left a lot of junk in there. You can delete any lines that are commented out, along with function msg(). I don't even know what that function's doing in there...

I think you were referring to the objects just fine. But, that little event.toElement seemed to be throwing an object expected error. The only reason I used the parent.frames[] method of calling the object is because I like it more since it's easier to insert a variable. However, the parent._mainFrame that you were using before should work just fine too.

The mseOver variable contains a boolean value to say whether or not the cursor is over a menu. In the offHover function the value is set to false (0), and then the user has 150 miliseconds to get back to the menu before it disappears. If they do hover over another menu, then mseOver is set to true (1).

The lastId variable keeps track of the last menu that was opened. It checks to see if you're over the same menu as you were last time, and if not, then it hides the menu stored in lastId. If this was not included then when you jumped between menu items in your image map, all the menus would stay open... It's kind of hard to explain...

Finally, yes, you could use an external .js document to build your menu on every page. Since your whole navigational system is JavaScript dependent anyway, its not going to cripple your site any less than before if the client doesn't have JavaScript support. Just be sure to include an alternate menu in the topFrame inside some <noscript> tags... Well, hope that helps some!