简体   繁体   中英

Drop Down Menu Issue

I am writing a drop-down menu for the school intranet site and I have created a rather strange issue. The sub-menus are offset from the selected menu y position by 36px. 在此输入图像描述

Here's a excerpt of the code (please excuse the quality :D)

<html>
<head>  
    <style>
    #navagationBar {
        margin: 0;
        padding: 0;
        z-index: 30;
    }

    #navagationBar li  {    
        list-style: none;
        float: left;
        font: bold 12px 'Arial';
        margin-left: 10px;
        width: 96px;
    }

    #navagationBar li a  {  
        display: block;
        margin: 0 1px 0 0;
        padding: 4px 10px;
        width: 136px;
        color: #FFFFFF;
        text-align: center;
        text-decoration: none;
    }

    #navagationBar li a:hover  {    
        background: #796952;
    }

    #navagationBar div  {   
        position: absolute;
        visibility: hidden;
        background: transparent; 
    }

    #navagationBar div a  { 
        position: relative;
        display: block;
        padding: 5px 10px;
        width: 136px;
        white-space: nowrap;
        text-align: left;
        text-decoration: none;
        background: #796952;  
        color: #FFF;
        font: 9px "Arial";
    }

    #navagationBar div a:hover  {   
        background: #969696;
        color: #FFF;
    }

    #navagationBar a  {
        color: #FFF;
    }

    div.navagation  {
        background: #2d221c;

        height: 28px;
    }

    div.sub  {
        left: 156px;
    }
    </style>
    <!-- BG COLOR: #2d221c
         FORERGROUND: #3c3429
         HOVER: #796952
         -->
    <script>    
            var menuItem = 0;
            var subItem = 0;

            var timeLimit = 250;
            var closeTimer = 0;
            var closeSubTimer = 0;


            // open menu
            function openMenu(id)  {
                stopTimer();

                // If a layer is already open close it
                if (menuItem)  {
                    menuItem.style.visibility = 'hidden';
                }

                // Then set the one clicked on by the user to be shown
                menuItem = document.getElementById(id);
                menuItem.style.visibility = 'visible';
            }

            function openSub(id)  {
                stopSubTimer();

                // If a layer is already open close it
                if (subItem)  {
                    subItem.style.visibility = 'hidden';
                }

                subItem = document.getElementById(id);
                subItem.style.visibility = 'visible';
            }

            function close()  {
                if (menuItem)  {
                    menuItem.style.visibility = 'hidden';
                }
            }

            function closeSub()  {
                if (subItem)  {
                    subItem.style.visibility = 'hidden';
                }
            }

            function startTimer()  {
                closeTimer = window.setTimeout(close, timeLimit);
            }

            function startSubTimer()  {
                closeSubTimer = window.setTimeout(closeSub, timeLimit);
            }

            // Stop timing
            function stopTimer()  {
                if (closeTimer)  {
                    window.clearTimeout(closeTimer);
                    closeTimer = null;
                }
            }

            // TODO: Make more modular          
            function stopSubTimer()  {
                if (closeSubTimer)  {
                    window.clearTimeout(closeSubTimer);
                    closeSubTimer = null;
                }
            }

            // If the user click out, close teh box
            document.onclick = close();
            document.onclick = closeSub();
    </script>
</head>
    <body>
        <div class="navagation">
            <ul id="navagationBar">
                <li><a href="#" onMouseOver="openMenu('menu0')" onMouseOut="startTimer()">HSIE</a>
                    <div id="menu0" onMouseOver="stopTimer()" onMouseOut="startTimer()">
                        <a href="#" onMouseOver="openSub('submenu0_0')" onMouseOut="startSubTimer()">Business Studies</a>
                        <div class='sub' id="submenu0_0" onMouseOver="openSub('submenu0_0')" onMouseOut="startSubTimer()">
                            <a href='view.php?id=110'>Year 11</a>
                            <a href='view.php?id=109'>Year 12</a>
                        </div>
                        <a href="#" onMouseOver="openSub('submenu0_1')" onMouseOut="startSubTimer()">Commerce</a>
                        <div class='sub' id="submenu0_1" onMouseOver="openSub('submenu0_1')" onMouseOut="startSubTimer()">
                            <a href='view.php?id=112'>Year 9</a>
                            <a href='view.php?id=111'>Year 10</a>
                        </div>
                        <a href="#" onMouseOver="openSub('submenu0_2')" onMouseOut="startSubTimer()">Geography</a>
                        <div class='sub' id="submenu0_2" onMouseOver="openSub('submenu0_2')" onMouseOut="startSubTimer()">
                            <a href='view.php?id=48'>Year 7</a>
                            <a href='view.php?id=92'>Year 8</a>
                            <a href='view.php?id=105'>Year 9</a>
                            <a href='view.php?id=70'>Year 10</a>
                            <a href='view.php?id=69'>Year 11</a>
                            <a href='view.php?id=131'>Year 12</a>
                        </div>
                        <a href="#" onMouseOver="openSub('submenu0_3')" onMouseOut="startSubTimer()">History</a>
                        <div class='sub' id="submenu0_3" onMouseOver="openSub('submenu0_3')" onMouseOut="startSubTimer()">
                            <a href='category.php?id=89'>Junior</a>
                            <a href='category.php?id=90'>Senior</a>
                        </div>
                    </div>
                </li>
            </ul>  
        </div>
    </body>
</html>

DOM Access

First, you have to make absolutely sure to not access the DOM by getElementbyId(); before the whole page has loaded.

You have to invoke the script right before the closing body tag or wrap your whole code in one function and invoke it at the end, right before the closing body tag. This is Yahoo! and Google Front-End Development best practice.

Alternatively you could use JQuery's $(document).ready() function or another JavaScript library's document-loaded function. Using a library for addressing just this issue, however would be overkill.

Global Variables

By declaring var menuItem = 0; outside the function scope, you declare the variable as a global, which is a very bad thing! It will clutter your entire Web site's namespace. Declare variables inside a function to create a closure.

Also you don't want to initialise your menuItem variable with an integer, because you will reference an object later on (a DOM object). Albeit Javascript doesn't need types to be dclared and this will work, it is creating confusion with the reader of the code. Just use var menuItem; inside the function.

CSS Block Formatting Context

Try using display: inline or display: block with your HTML elements. Make sure to read and understand the W3C CSS Visual formatting model .

Try putting the sub menu divs before the corresponding a tags (instead of putting these divs after them).

For instance, try this:

<div class='sub' id="submenu0_0" onMouseOver="openSub('submenu0_0')" onMouseOut="startSubTimer()">
    <a href='view.php?id=110'>Year 11</a>
    <a href='view.php?id=109'>Year 12</a>
</div>
<a href="#" onMouseOver="openSub('submenu0_0')" onMouseOut="startSubTimer()">Business Studies</a>

Instead of this:

<a href="#" onMouseOver="openSub('submenu0_0')" onMouseOut="startSubTimer()">Business Studies</a>
<div class='sub' id="submenu0_0" onMouseOver="openSub('submenu0_0')" onMouseOut="startSubTimer()">
    <a href='view.php?id=110'>Year 11</a>
    <a href='view.php?id=109'>Year 12</a>
</div>

You have individual IDs for each sub level so you could add styling for each.

#submenu0_0 > a {top:0px;}
#submenu0_1 > a {top:25px;}
#submenu0_2 > a {top:50px;}
#submenu0_3 > a {top:75px;}

Is this due to quirks mode ?

Try using a proper doctype like this:

<!DOCTYPE HTML>
<html>
<head>

</head>
<body>

</body>
</html>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM