我正在为学校内部网站点编写一个下拉菜单,我创建了一个相当奇怪的问题。子菜单从所选菜单y位置偏移36px。
以下是代码的摘录(请原谅质量: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 :(得分:1)
DOM访问
首先,您必须确保在整个页面加载之前不getElementbyId();
访问DOM。
您必须在关闭正文标记之前调用脚本,或者将整个代码包装在一个函数中并在结束时调用它,就在关闭正文标记之前。这是雅虎!和Google前端开发最佳实践。
或者,您可以使用JQuery的$(document).ready() function
或其他JavaScript库的文档加载函数。然而,使用库来解决这个问题可能会有点过分。
全局变量
通过在函数范围外声明var menuItem = 0;
,可以将变量声明为全局变量,这是一件非常糟糕的事情!它会使整个Web站点的命名空间变得混乱。在函数内声明变量以创建闭包。
此外,您不希望使用整数初始化您的menuItem变量,因为您稍后将引用一个对象(一个DOM对象)。虽然Javascript不需要类型直播,这将起作用,它会与代码的读者产生混淆。只需在函数中使用var menuItem;
。
CSS块格式上下文
尝试将display: inline
或display: block
与HTML元素一起使用。请务必阅读并理解W3C CSS Visual formatting model。
答案 1 :(得分:1)
尝试将子菜单div放在相应的标签之前(而不是将这些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>
答案 2 :(得分:0)
每个子级别都有单独的ID,因此您可以为每个子级别添加样式。
#submenu0_0 > a {top:0px;}
#submenu0_1 > a {top:25px;}
#submenu0_2 > a {top:50px;}
#submenu0_3 > a {top:75px;}
答案 3 :(得分:0)