2012-08-07 178 views
0

我正在为学校Intranet网站编写一个下拉菜单,并且我创建了一个相当奇怪的问题。子菜单从所选菜单y位置偏移36px。 enter image description here下拉菜单问题

下面的代码的摘录(请原谅质量: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> 
+0

内嵌的JavaScript,哎呀!它燃烧! – Undefined 2012-08-07 10:23:59

+0

@Sam我很懒;) – Darestium 2012-08-07 10:24:51

回答

1

尝试将子菜单div放在相应的a标签之前(而不是将这些div放在它们后面)。

例如,试试这个:

<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> 

取而代之的是:

<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> 
+1

+1好的先生,我谢谢你!这样简单的解决方案! – Darestium 2012-08-07 10:41:06

1

DOM访问

首先,你必须绝对确保不被getElementbyId();访问DOM在整个页面加载之前。

您必须在关闭主体标记之前调用脚本,或者将整个代码包装在一个函数中,并在结束时在关闭主体标记之前调用它。这是Yahoo!和Google前端开发最佳做法。

或者,您可以使用JQuery的$(document).ready() function或其他JavaScript库的文档加载功能。使用一个库来解决这个问题,但是会是矫枉过正。

全局变量

通过声明VAR menuItem = 0;功能范围之外,您变量声明为一个全球性的,这是一个非常糟糕的事情!它会混乱你的整个网站的命名空间。在函数内声明变量以创建闭包。

此外,你不想用一个整数初始化你的menuItem变量,因为稍后你会引用一个对象(一个DOM对象)。尽管Javascript不需要类型来声明,但这会起作用,它会与代码的读者产生混淆。在功能里面只需使用var menuItem;

CSS块格式化上下文

使用display: inlinedisplay: block与HTML元素尝试。请务必阅读并理解W3C CSS Visual formatting model

0

你必须为每个子水位个人ID,这样你可以为每个添加样式。

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

这是由于quirks mode

尝试使用正确的doctype这样的:

<!DOCTYPE HTML> 
<html> 
<head> 

</head> 
<body> 

</body> 
</html>