Link to home
Start Free TrialLog in
Avatar of IDEASDesign
IDEASDesign

asked on

Need help with custom css-based dropdown menus

I've been trying to implement custom dropdown menus for my "Shop" and "Brands" button on the new shopping cart I'm developing:

http://www.isadorapopper.com/index.cfm

I'm doing this using CSS, and feel that I'm about 75% there.  But if possible, I'd be grateful for some assistance with the following:

1) I can't seem to reliably control when my menus should disappear.  Since each of the 2 menus is being displayed in it's own div, .. I assumed that having something like the following would do the trick:

<div id="sec1" style="position:absolute;width:125px;background-color:#89BE3A;text-align:left;visibility:hidden;z-index:5;padding:10px;border:1px solid #285C12;" onMouseout="hideSec(1);"><cfinclude template="put_shopmenus.cfm"></div>

But this isn't working very well at all.  In fact, it seems that the hideSec() function is also being triggered onMouseover. So basically, whenever you move the mouse pointer over the div, .. the menu disappears after a few seconds (I currently have a setTimeout function in the hideSec() function).  I've tried adding the showSec() and hideSec() functions to the links in the dropdown menus, but that seems to be problematic as well.  How can I accomplish the desired effect?  (menus stay visible when the mousepointer is over them, and then disappear when the mouse pointer is moved away from it).

Thanks!
- Yvan

 


Avatar of numbers1to9
numbers1to9

This is the simplest form of a drop down menu, does this do anything for you?

<div style="position:relative;
            width:auto; <!-- change to change the area that triggers the mouse in/out -->
            height:auto;
            background-color:#89BE3A;"

            onmouseover="document.getElementById('menu').style.visibility = 'visible'"
            onmouseout="document.getElementById('menu').style.visibility = 'hidden'"
>MENU</div>

<div id="menu"
     style="position:relative;
            width:200px;
            padding:10px;
            height:auto;
            background-color:#89BE3A;
            visibility:hidden;"

            onmouseover="document.getElementById('menu').style.visibility = 'visible'"
            onmouseout="document.getElementById('menu').style.visibility = 'hidden'"
>

  <ol>
   <li>option</li>
   <li>option</li>
   <li>option</li>
  </ol>

</div>
Avatar of IDEASDesign

ASKER

Your solution works great - thank you!  

There's just one small problem  -- I can't seem to be able to attach an onMouseout event to the Shop or Brands links/buttons (to trigger the hiding the layer).

In other words, .. there will be situations where users move their mouse pointer over the Shop or Brands buttons -- but NOT move their mouse pointer over any of the links in the popup menu (they might just want to look at the pretty menu). What then happens is that the popup menu never disappears -- it remains frozen on the screen until the user interacts with it)   I've found that if I attach my hideSec() function to the Shop and Brands buttons using onMouseout, .. that I'm right back where I started, .. where my layer hides itself after a few seconds.  

How can I code around this?

- Yvan
>I can't seem to be able to attach an onMouseout event to the Shop or Brands links/buttons

Why not?

<a href="javascript:void(0);" class="topnavlinks" onmouseover="showSec(1);hideSecNow(2);document.getElementById('menu').style.visibility = 'hidden'">Shop</a>       

Should suffice, no?

I'm not quite fallowing you on what you're saying.

Given that I can't see your JavaScript code it's hard for me to say something else. You need to define the mouseout=hide with the menu-button.

The other way of doing this is creating a mouse over for every other object on the page and hide the menu when the mouse moves over any other object than the menu -- this is of course not a good way to do this; probably the worst.

Check to see that all names are in order, e.g. I noticed that you have no "id" for the dropdown menu, i.e. <div class="shoplinks"> should be <div id="menu" class="shoplinks"> if the document.getElementById('menu') is going to find the div.
Why not, ... you ask?

Because as soon as I mouse my move pointer off of the Shop / Brand button -- the menu disappears before I have a chance to move my mouse pointer over it.  

The javascript for my showSec/HideSec functions is as follows:

ns4 = (document.layers) ? true:false //required for Functions to work
ie4 = (document.all) ? true:false //required for Functions to work
ng5 = (document.getElementById) ? true:false //required for Functions to work

//function hideSec() {
//if (ng5) document.getElementById('sec1').style.visibility = "hidden"
//else if (ns4) document.sec1.visibility = "hide"
//else if (ie4) sec1.style.visibility ="hidden"

//if (ng5) document.getElementById('sec2').style.visibility = "hidden"
//else if (ns4) document.sec2.visibility = "hide"
//else if (ie4) sec2.style.visibility ="hidden"
//}

function showSec(n) {
if (ng5) document.getElementById('sec' + n).style.visibility = "visible";
else if (ns4) document.layers["sec" + n].visibility = "show";
else if (ie4) document.all["sec" + n].style.visibility = "visible";
}

function hideSec(n) {
if (ng5) setTimeout("document.getElementById(\'sec"+ n+"\').style.visibility = 'hidden'",2500);
else if (ns4) setTimeout("document.layers[\'sec" + n+"\'].visibility = 'hide'",2500);
else if (ie4) setTimeout("document.all[\'sec" + n+"\'].style.visibility = 'hidden'",2500);
}

function hideSecNow(n) {
if (ng5) document.getElementById('sec' + n).style.visibility = 'hidden';
else if (ns4) document.layers["sec" + n].visibility = "hide";
else if (ie4) document.all["sec" + n].style.visibility = "hidden";
}

I'm sorry but your function doesn't make any sense.

I am going to do some serious surgery...

===========================

<html><head><script type="text/javascript">

ns4 = (document.layers) ? true:false //required for Functions to work
ie4 = (document.all) ? true:false //required for Functions to work
ng5 = (document.getElementById) ? true:false //required for Functions to work

function showSec(n) {
if (ng5) document.getElementById('sec' + n).style.visibility = "visible";
else if (ns4) document.layers["sec" + n].visibility = "show";
else if (ie4) document.all["sec" + n].style.visibility = "visible";
}

function hideSec(n) {
if (ng5) document.getElementById('sec' + n).style.visibility = "hidden";
else if (ns4) document.layers["sec" + n].visibility = "hide";
else if (ie4) document.all["sec" + n].style.visibility = "hidden";
}

</script>

</head><body>

<a href="javascript:void(0);" onmouseover="showSec(1)" onmouseout="hideSec(1)">Shop</a>
<a href="javascript:void(0);" onmouseover="showSec(2)" onmouseout="hideSec(2)">Brands</a>


<div id="sec1" style="position:absolute;
                      width:125px;
                      background-color:#89BE3A;
                      text-align:left;
                      visibility:hidden;
                      z-index:5;
                      padding:10px;
                      border:1px solid #285C12;"
                      onmouseover="showSec(1)"
                      onmouseout="hideSec(1)">
<div class="shoplinks">
<a href="http://www.isadorapopper.com/index.cfm?category=4" class="shoplinks">Books</a><br/>
<a href="http://www.isadorapopper.com/index.cfm?category=7" class="shoplinks">Coffee & Tea</a><br/>
<a href="http://www.isadorapopper.com/index.cfm?category=5" class="shoplinks">Cookware</a><br/>
<a href="http://www.isadorapopper.com/index.cfm?category=3" class="shoplinks">Furnishings</a><br/>
<a href="http://www.isadorapopper.com/index.cfm?category=2" class="shoplinks">Kitchen Cleaning</a><br/>
<a href="http://www.isadorapopper.com/index.cfm?category=1" class="shoplinks">Specialty Foods</a><br/>
<a href="http://www.isadorapopper.com/index.cfm?category=6" class="shoplinks">Table Top</a><br/>
</div>
</div>

<div id="sec2" style="position:absolute;
                      width:125px;
                      background-color:#89BE3A;
                      text-align:left;
                      visibility:hidden;
                      z-index:10;
                      padding:10px;
                      margin-left:35px;
                      border:1px solid #285C12;"
                      onmouseover="showSec(2)"
                      onmouseout="hideSec(2)">
<div class="shoplinks">
<a href="http://www.isadorapopper.com/index.cfm?fuseaction=product.list&&mfg_account_id=5" class="shoplinks">Bodum</a><br/>
<a href="http://www.isadorapopper.com/index.cfm?fuseaction=product.list&&mfg_account_id=6" class="shoplinks">Caldrea</a><br/>
<a href="http://www.isadorapopper.com/index.cfm?fuseaction=product.list&&mfg_account_id=7" class="shoplinks">Chronicle Books</a><br/>
<a href="http://www.isadorapopper.com/index.cfm?fuseaction=product.list&&mfg_account_id=4" class="shoplinks">Emile Henry</a><br/>
<a href="http://www.isadorapopper.com/index.cfm?fuseaction=product.list&&mfg_account_id=3" class="shoplinks">Gel Mat</a><br/>
<a href="http://www.isadorapopper.com/index.cfm?fuseaction=product.list&&mfg_account_id=1" class="shoplinks">Lettuce Lizzie</a><br/>
<a href="http://www.isadorapopper.com/index.cfm?fuseaction=product.list&&mfg_account_id=8" class="shoplinks">Miscellaneous</a><br/>
<a href="http://www.isadorapopper.com/index.cfm?fuseaction=product.list&&mfg_account_id=2" class="shoplinks">Stonewall Kitchen</a><br/>
</div>
</div>

<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>

</body>
</html>

===============================================

Try that one, it should do exactly what you want.
( I tried it in Fx, it should work in IE also, however when I tried it in IE 6 the CSS was kind of a little out of align, you may want to see to that).

One more thing:

between the word and the menu there is a little gap. If the user moves the mouse to slow or  else gets somehow into that gap the menu will shut down.

To fix this: either move the layer margin 1-2px up or use span for the button holders.
>> between the word and the menu there is a little gap. If the user moves the mouse to slow or  else gets somehow into that gap the menu will shut down.

Those aren't buttons.  Those are just plain hyperlinks inside a div that contains a tiling background image. That's whay I kept referring to those as "buttons/links" in my original post.

For that reason, ... what you're suggesting that I do won't work.  The mouse pointer will always need to move over the gap. Can you offer a solution for this?

Also, .. I already have this displaying correctly in IE6.  Do you have any way to correct the differences/problems that your code would introduce?  Because I've already invested a lot of time in ensuring that my code works consistently in all 3 browsers, and that the CSS positioning is correct in each.

- Yvan





>>For that reason, ... what you're suggesting that I do won't work.  The mouse pointer will always need to move over the gap. Can you offer a solution for this?

As you may have noticed: the onmouseover is set in the DIV (not a href). In other words, set the mouseover to the div/span that holds the text. Keep in mind then that it will be enough for the user to move the mouse over the container to activate the menu.

Regarding the "gap" (for the div-solution I gave) it is a CSS issue. In IE 6.0 and Opera 9.21 there is no "gap". To fix this I would, like previously stated, move the margin up 1 or 2 px (-2px), or as needed.

I do not think you can fix the "gap" that exist when you use plain text. What you can do however, if you really want to activate the menu only, and only, when the users hovers above the text (and not the entire div) is this:  

create a span to hold your href, make sure that the span either is set to "lock" to the bottom of the "button holder" or set its height to stretch all the way to the bottom. This will create a "box" around your href (and just your href), and when you set onmouse in/out on that span layer it will only activate itself when the user moves over the text and keep being activated when the mouse moves down and until it reaches the pop up menu.


>>Also, .. I already have this displaying correctly in IE6.  Do you have any way to correct the differences/problems that your code would introduce?  Because I've already invested a lot of time in ensuring that my code works consistently in all 3 browsers, and that the CSS positioning is correct in each.

My code shouldn't introduce any discrepancies; it is basically exactly the same code you gave, but slightly changed (compare them, notice the difference?; all I did was to remove all the time handlers). I tried it in Firefox 2.0, IE 6.0, and Opera 9.21, and it works like a charm.

And there shouldn't be any CSS issues, really.

Think about it, all the code does is set the layers visibility, nothing else. All you need to do is set the new function to be activated on the correct layer (see my recommendations above) and do the same for your pop up menus.




Sorry , .. but that's definitely not working for me.  

http://www.isadorapopper.com/index.cfm

This is a mess, actually, and works totally unlike the way you described.

I appreciate your efforts, but we're definitely going down the wrong path here.

- yg




ASKER CERTIFIED SOLUTION
Avatar of numbers1to9
numbers1to9

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks so much for all your help with this.  As it turns out, there were lots of things interfering with your ability to view and interpret my source code consistently (cached CFCs and session variables - unintentional nested divs - my tinkering with it in between experts exchange viewings, etc).  I finally got it working correctly after recognizing and correcting these things:

http://www.isadorapopper.com/index.cfm

I had stubbornly assumed all along that the hiding of the layer couldn't be prevented onMouseout if the gap was eliminated.  I tried using SPANs like you suggested, but found that I couldn't control the height of those.  So I instead ended up using a table (You can view my source code to see what I mean).

The solution works identically in Firefox, UE6, IE7, .. and even Safari for Windows :)

Thanks for your help!  I've awarded you the 500 points.
- Yvan
You're welcome.