470,591 Members | 1,484 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 470,591 developers. It's quick & easy.

Popup menu problems

I'm having problems getting my popup menu to work correctly, and was
hoping someone here could point me in the right direction. I have the
following script:

<script>
var activeMenu="";

function getObject(id) {
var object=eval("document.getElementById('"+id+"')");
return object;
}

function PopMenu(M) {
clearTimeout();
HideActive();
getObject(M).style.visibility="visible";
activeMenu=M;
}

function HideActive() {
if (activeMenu !="") {
getObject(activeMenu).style.visibility="hidden";
activeMenu="";
}
}

function menuTimeout() {
setTimeout("HideActive()", 2000);
}
</script>

which goes with the following html:

<div id="menuhead" onMouseOver="PopMenu('menu')">
<img src="menuhead.gif" />
</div>
<div id="menu" onMouseOut="menuTimeout()">
<a href="test1.htm">Test 1</a>
<a href="test2.htm">Test 2</a>
<a href="test3.htm">Test 3</a>
</div>
The menu opens perfectly, but it closes 2 sec after I mouseOut() of
'menuhead' instead of the actual 'menu'. Also, if I repeatly
mouseOver() the 'menuhead', the timing gets thrown off, as if
clearTimeout() is being called irregularly. Could someone with more
experience give me a hand?

Thanks,
Aaron

Jul 23 '05 #1
5 3122
Aaron wrote:
I'm having problems getting my popup menu to work correctly, and was
hoping someone here could point me in the right direction. I have the
following script:


Here's an alternative approach:

<style type="text/css">
#menu {
position: absolute;
clip: rect(auto auto 15px auto)
}
</style>
....
<div id="menu"
onmouseout="style.clip='rect(auto auto 15px auto)'"
onmouseover="style.clip='rect(auto auto auto auto)'">
Show menu<br />
<a href="test1.htm">Test 1</a>
<a href="test2.htm">Test 2</a>
<a href="test3.htm">Test 3</a>
</div>
JW

Jul 23 '05 #2
Here's an alternative approach:

<style type="text/css">
#menu {
position: absolute;
clip: rect(auto auto 15px auto)
}
</style>
...
<div id="menu"
onmouseout="style.clip='rect(auto auto 15px auto)'"
onmouseover="style.clip='rect(auto auto auto auto)'">
Show menu<br />
<a href="test1.htm">Test 1</a>
<a href="test2.htm">Test 2</a>
<a href="test3.htm">Test 3</a>
</div>


This works great...thanks so much, JW. Now, to get the setTimeout(),
I've changed it to the following:

<style type="text/css">
#menu {position: absolute;
clip: rect(auto auto 15px auto);
}
</style>
<script type="text/javascript">
function getObject(id) {
var object=eval("document.getElementById('"+id+"')");
return object;
}
function openMenu(id) {
var name=getObject(id);
name.style.clip='rect(auto auto auto auto)';
}
function closeMenu(id) {
var name=getObject(id);
name.style.clip='rect(auto auto 15px auto)';
}
function menuTimeout(id) {
setTimeout("closeMenu(id)", 2000);
}
</script>
<div id="menu" onmouseout="menuTimeout('menu')"
onmouseover="openMenu('menu')">
<p>Show menu</p>
<ul>
<li><a href="test1.htm">Test 1</a></li>
<li><a href="test2.htm">Test 2</a></li>
<li><a href="test3.htm">Test 3</a></li>
</ul>
</div>

Passing the id name to the menuTimeout() function doesn't seem to work
at all. What am I doing wrong here?

Thanks,
Aaron
Jul 23 '05 #3
Aaron <ag********@comcast.not> writes:
I'm having problems getting my popup menu to work correctly, and was
hoping someone here could point me in the right direction. I have the
following script:
I'll try to give some suggestions that you can try.
<script>
The "type" attribute is required in HTML.
<script type="text/javascript">
var activeMenu="";

function getObject(id) {
var object=eval("document.getElementById('"+id+"')");
You *never* need to use eval for accessing elements by name. You
probably never need to use eval at all, and shouldn't, since there are
more efficient and less error prone alternatives. This function can
just be written:

return document.getElementById(id);
return object;
}

function PopMenu(M) {
clearTimeout();
The function "clearTimeout" takes an argument: the value returned by
the call to setTimeout that you want to cancel.
<URL:http://www.mozilla.org/docs/dom/domref/dom_window_ref8.html#1016919>
<URL:http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/cleartimeout.asp>

Make a global variable outside the function,
var timeout_id;
and call
clearTimeout(timeout_id);
timeout_id = null;
and set it again when you call setTimeout.
HideActive();
getObject(M).style.visibility="visible";
activeMenu=M;
}

function HideActive() {
if (activeMenu !="") {
getObject(activeMenu).style.visibility="hidden";
activeMenu="";
}
}

function menuTimeout() {
setTimeout("HideActive()", 2000);
first clear the existing timeout, if any:
if (timeout_id != null) { clearTimeout(timeout_id); }
This avoids having two timeouts running at the same time,
when you can only cancel one.

and then start a new countdown:
timeout_id = setTimeout("HideActive()",2000):
(or even
timeout_id = setTimeout(HideActive, 2000);
in modern browsers)
}
</script>

which goes with the following html:

<div id="menuhead" onMouseOver="PopMenu('menu')">
<img src="menuhead.gif" />
You should not write "/>" in HTML. It is only for XHTML, which you
don't seem to use (attribute names are all lower case in XHTML).
The menu opens perfectly, but it closes 2 sec after I mouseOut() of
'menuhead' instead of the actual 'menu'.
Not for me. When I try your code in IE 6 (without the image :),
the submenu starts visible. When I put the mouse over it and leaves
again, the submenu disappears after two seconds (even if I am, at that
point, over the menuhead ... most likely because clearTimeout fails to
do anything).
Also, if I repeatly
mouseOver() the 'menuhead', the timing gets thrown off, as if
clearTimeout() is being called irregularly.


clearTimeout, as you call it, does nothing, so every mouseout will
schedule a hide, with the only limit to how many you can have pending
being how fast you can twiddle your moust.

Good luck.
/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Jul 23 '05 #4
Aaron <ag********@comcast.not> writes:
<style type="text/css">
#menu {position: absolute;
clip: rect(auto auto 15px auto);
I would recommend changing "15px" to "1.2em" (or whatever the line
height is). To see why, try adding:
font-size: large;
That can happen to people with different default font settings too.
function menuTimeout(id) {
setTimeout("closeMenu(id)", 2000);


This won't work. The code
closeMenu(id)
will be executed in the global context, and will not have access
to the local variables of the menuTimeout function, including "id".

You can either use:
setTimeout("closeMenu('"+id+"');", 2000);
(i.e., build the id into the expression as a string literal) or
setTimeout(function(){closeMenu(id);}, 2000);
(use a closure to capture the value of "id").

See my other reply for other suggestions.
/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Jul 23 '05 #5
Thanks for help, Lasse. Works great now.

Aaron

Jul 23 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by PC User | last post: by
2 posts views Thread by ouech | last post: by
2 posts views Thread by SamSpade | last post: by
7 posts views Thread by anthony.turcotte | last post: by
9 posts views Thread by john | last post: by
1 post views Thread by =?Utf-8?B?Q2hyaXN0aWFuIEphY29i?= | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.