views:

514

answers:

3

Hello!

Based on this tutorial, I've built a drop down menu for template from Styleshout.com. medigerati helped me so that it works now - at least in Firefox 3.5 and Internet Explorer 8.

You can see the menu in action here.

But unfortunately, it doesn't work well in all browsers. In Internet Explorer 6 - for example - it isn't displayed correctly.

Could you please tell me how I can improve the code to make it work in more browsers?

I hope you can help me. Thanks in advance!

HTML:

<ul id="nav">
    <li><a href="index.html">Nav #1</a>
        <ul>
            <li><a href="#">Nav #1.1</a></li>

            <li><a href="#">Nav #1.2</a></li>
        </ul>
    </li>
    <li><a href="index.html">Nav #2</a>
        <ul>
            <li><a href="#">Nav #2.1</a></li>
            <li><a href="#">Nav #2.2</a></li>

        </ul>
    </li>
    <li><a href="index.html">Nav #3</a>
        <ul>
            <li><a href="#">Nav #3.1</a></li>
            <li><a href="#">Nav #3.2</a></li>
        </ul>

    </li>
</ul>

CSS:

ul#nav li ul {
    position: absolute;
    left: -9999px;
    top: 100%;
    display: block;
    width: 100px;
    background-color: transparent;
}
ul#nav li {
    position: relative;
    float: left;
}
/* Links in the drop down lists start */
ul#nav li ul li a {
    clear: left;
    display: block;
    text-decoration: none;
    width: 100px;
    background-color: #333;
}
/* Links in the drop down lists end */
/* Making visible start */
ul#nav li:hover ul, #nav li.sfhover ul {
    left: auto;
}
/* Making visible end */

JavaScript:

sfHover = function() {
    var sfEls = document.getElementById("nav").getElementsByTagName("LI");
    for (var i=0; i<sfEls.length; i++) {
        sfEls[i].onmouseover=function() {
            this.className+=" sfhover";
        }
        sfEls[i].onmouseout=function() {
            this.className=this.className.replace(new RegExp(" sfhover\\b"), "");
        }
    }
}
if (window.attachEvent) window.attachEvent("onload", sfHover);
A: 

Look at the Dojo Toolkit toolbar widget. Dojo works consistently across all browsers, and even provides accessibility for handicapped users.

The menu widget when anchored to the page (as seen in the example) may also be what you're looking for.

Wahnfrieden
+1  A: 

Javascript event binding works differently in different browsers. Try:

sfHover = function() {
    var sfEls = document.getElementById("nav").getElementsByTagName("LI");
    for (var i=0; i<sfEls.length; i++) {
        addEvent(sfEls[i], "mouseover", function() {
            this.className+=" sfhover";
        });
        addEvent(sfEls[i], "mouseout", function() {
            this.className=this.className.replace(new RegExp(" sfhover\\b"), "");
        });
    }
}

function addEvent(el, name, func) {
    if (el.attachEvent)
        el.attachEvent("on" + name, func);
    else
        el.addEventListener(name, func, false);
}

addEvent(window, "load", sfHover);

Quirksmode.org has a lot of good articles about events.

Joel Potter
Thank you. But what exactly are the differences between my old code and your new code?
Notice the addEvent function? That function attaches events in a cross browser compatible way. This is necessary, because not all browsers like `sfEls[i].onmouseout = ` or `element.attachEvent(...)`.
Joel Potter
It doesn't work! At first, I thought it would but not I see that it doesn't. The menus drop down correctly. But they don't close anymore. See here: http://wp1080088.wp029.webpack.hosteurope.de/Refresh1-1/ What can I do? Why is this?
I think I've got the problem: The JavaScript code adds something to the classname of the LIs. But there was no classname. So I added [class="menueintrag"] everywhere. The class "menueintrag" has no reference in the CSS code but now it seems to work. Is this the correct way of solving the problem? Was this the reason?
It's possible I guess if `this.className` was returning a null. But I thought it would return an empty string if the attribute wasn't specified. Try using `class=""` instead of `class="menueintrag"`, see if that works too.
Joel Potter
No, this doesn't work. It's a logical error: "menueintrag" + " sfhover" gives "menueintrag sfhover". This is a correct listing of multiple classes. But " " and " sfhover" gives " sfhover" which is a wrong class name since it starts with a blank space.
+1  A: 

Are you doing this as a learning exercise, or do you just want a good nav-bar type menu? If the latter, I would recommend YUI 3.0’s MenuNav, which is well-tested against all major browsers, including IE6.

Nate