自己写的很啰嗦,所以为转载文章
html
<div id="nav" class="container">
<ul>
<li>
<a href="javascript:;">站长之家</a>
</li>
<li>
<a href="javascript:;">行业资讯</a>
<div class="subnav">
<em class="arrow"></em>
<p>
<span>
<a href="javascript:;">业界动态</a>|
<a href="javascript:;">收购融资</a>|
<a href="javascript:;">门户动态</a>|
<a href="javascript:;">搜索引擎</a>|
<a href="javascript:;">网络游戏</a>|
<a href="javascript:;">电子商务</a>|
<a href="javascript:;">广告传媒</a>|
<a href="javascript:;">厂商开发</a>
</span>
</p>
</div>
</li>
<li><a href="javascript:;">站长在线</a>
<div class="subnav">
<em class="arrow"></em>
<p>
<span>
<a href="javascript:;">站长报道</a>|
<a href="javascript:;">好站推荐</a>|
<a href="javascript:;">站长聚会</a>|
<a href="javascript:;">站长访谈</a>|
<a href="javascript:;">站长茶馆</a>|
<a href="javascript:;">站长排行</a>
</span>
</p>
</div>
</li>
<li><a href="javascript:;">网站运营</a>
<div class="subnav">
<em class="arrow"></em>
<p>
<span>
<a href="javascript:;">建站经验</a>|
<a href="javascript:;">策划盈利</a>|
<a href="javascript:;">搜索优化</a>|
<a href="javascript:;">网站推广</a>|
<a href="javascript:;">免费资源</a>
</span>
</p>
</div>
</li>
<li><a href="javascript:;">设计在线</a>
<div class="subnav">
<em class="arrow"></em>
<p>
<span>
<a href="javascript:;">酷站推荐</a>|
<a href="javascript:;">网页设计</a>|
<a href="javascript:;">WEB标准</a>|
<a href="javascript:;">视频处理</a>|
<a href="javascript:;">设计活动</a>
</span>
</p>
</div>
</li>
<li><a href="javascript:;">网络编程</a>
<div class="subnav">
<em class="arrow"></em>
<p>
<span>
<a href="javascript:;">Asp编程</a>|
<a href="javascript:;">Php编程</a>|
<a href="javascript:;">.Net编程</a>|
<a href="javascript:;">Xml编程</a>|
<a href="javascript:;">Access</a>|
<a href="javascript:;">Mssql</a>|
<a href="javascript:;">Mysql</a>
</span>
</p>
</div>
</li>
<li><a href="javascript:;">行业资讯</a>
<div class="subnav">
<em class="arrow"></em>
<p>
<span>
<a href="javascript:;">联盟动态</a>|
<a href="javascript:;">联盟介绍</a>|
<a href="javascript:;">联盟点评</a>|
<a href="javascript:;">网赚技巧</a>
</span>
</p>
</div>
</li>
<li><a href="javascript:;">服务器</a>
<div class="subnav">
<em class="arrow"></em>
<p>
<span>
<a href="javascript:;">Web服务器</a>|
<a href="javascript:;">Ftp服务器</a>|
<a href="javascript:;">Mail服务器</a>|
<a href="javascript:;">Dns服务器</a>|
<a href="javascript:;">Win服务器</a>|
<a href="javascript:;">Linux服务器</a>|
<a href="javascript:;">安全防护</a>|
<a href="javascript:;">虚拟主机</a>
</span>
</p>
</div>
</li>
</ul>
</div>
导航一般都用ul括起来
<ul>
<li><a></a></li>
<li><a></a></li>
</ul>
<a>标签中的href不为空,设置为"javascript:;"
,因为这样点击页面不会刷新
每个元素的背景图片都是同一张图片的不同位置,所以subnav
的背景是副标题的最左边,p
的背景是副标题 的最右,span
的背景是所有链接的背景
css
基本css
body,div,ul,li,p{
margin:0;
padding:0;
}
body{
font:12px/1.5 Arial;
}
ul{
list-style-type:none;
}
添加背景图片
#nav,#nav ul,#nav ul li,#nav ul li a:hover,#nav .subnav,#nav .subnav p,#nav .subnav p span,#nav .subnav .arrow{
background:url(http://fgm.cc/learn/lesson4/img/nav_bg.png) no-repeat;
}
元素样式
/*最外层设置宽度,位置*/
#nav{
position:relative;/*对二级标题的位置设置有用*/
width:910px;
background-position:0 -36px;/*这是设置最左边的背景,属性值是相对于原来的位置偏移多少*/
margin:10px auto;
}
/*ul设置高度还有整体的导航栏的左右宽度,多余的部分都隐藏起来*/
#nav ul{
height:36px;
line-height:36px;
margin-left:10px;
padding-right:10px;
overflow:hidden;
background-position:right -72px;/*设置最右边的背景*/
}
/*ul的li需要全部靠左浮动,浮动后元素就可以设置宽高*/
#nav ul li{
float:left;
width:110px;
margin-left:-2px;
background-position:0 -108px;
}
/*主要是设置字大小,颜色,居中显示,去掉<a>原来的修饰*/
#nav ul li a{
font-size:14px;
color:#fff;
width:102px;
display:block;
text-align:center;
text-decoration:none;
margin:0 2px 0 4px;
}
/*设置hover后的变化*/
#nav ul li a:hover{
font-weight:700;
background-position:-3px -144px;
}
/*下面是设置二级标题,类似于一级标题*/
#nav .subnav{
display:none;
position:absolute;
top:41px;
width:auto!important;
min-width:110px;
height:27px;
line-height:27px;
white-space:nowrap;/*规定段落中的文本不进行换行*/
background-position:0 -180px;
}
#nav .subnav p{
margin-left:10px;
padding-right:10px;
background-position:right -234px;
}
#nav .subnav p span{
display:block;
color:#235e99;
background-repeat:repeat-x;/*沿着x轴的方向重复*/
background-position:0 -207px;
}
#nav .subnav p a{
font-size:12px;
display:inline;/*a标签会继承父元素的display*/
color:#235e99;
text-decoration:none;
margin:0 5px;
padding:0 2px;
}
#nav .subnav p a:hover{
font-weight:400;
background-image:none;
border-bottom:2px solid;
}
#nav .subnav .arrow{
position:absolute;
top:-4px;
display:block;
width:11px;
height:5px;
background-position:0 -261px;
}
背景图片
background-positon
背景图片显示的起始位置,负值代表图片向左向上移动,正值代表图片向右向下移动
ol
ul
本身的padding-left有40px
em.arrow
为箭头
subnav
的背景图为左边圆角, p
为右边圆角, span
的背景图为内容背景图,沿x轴方向重复
JS部分
var get = {
byId: function (id) {
return document.getElementById(id)
},
byClass: function (sClass, oParent) {
// 返回父元素oParent内类名为sClass的元素
var aClass = [];
var reClass = new RegExp("(^|)"+sClass+"(|$)");
var aElem = this.byTagName('*', oParent);
for (var i=0; i<aElem.length; i++) {
reClass.test(aElem[i].className) && aClass.push(aElem[i]);
}
// return 放在for循环中,就不能循环,执行到return直接结束,return后的console.log()也不能执行
return aClass;
},
byTagName: function (elem, obj) {
// 返回 obj 下的 名为 elem 的 tag
return (obj || document).getElementsByTagName(elem);
}
};
window.onload = function () {
var oNav = get.byId('nav');
var aLi = get.byTagName('li', oNav);
var aSubNav = get.byClass('subnav', oNav);
var oSubNav = oEm = timer = null;
var i = 0;
for (i=1; i<aLi.length; i++) {
aLi[i].onmouseover = function () {
// 隐藏所有子菜单
for (i=0; i<aSubNav.length; i++) aSubNav[i].style.display = 'none';
// 获取该项下的子菜单
oSubNav = get.byClass('subnav', this)[0];
console.log(oSubNav);
// 获取该项下的指示箭头
oEm = get.byTagName('em', this)[0];
// 显示该项下的子菜单
oSubNav.style.display = 'block';
// 判断显示区域
console.log(oNav.offsetWidth - this.offsetLeft > oSubNav.offsetWidth)
oNav.offsetWidth - this.offsetLeft > oSubNav.offsetWidth ?
// 如果在显示范围居左显示, 超出显示范围居右显示
oSubNav.style.left = this.offsetLeft + 'px' : oSubNav.style.right = 0;
// 计算指标箭头显示位置
oEm.style.left = this.offsetLeft - oSubNav.offsetLeft + 50 + 'px';
clearTimeout(timer);
// 阻止冒泡事件
oSubNav.onmouseover = function (event) {
(event || window.event).cancelBubble = true;
clearTimeout(timer)
}
};
aLi[i].onmouseout = function () {
timer = setTimeout(function () {
oSubNav.style.display = 'none'
}, 300)
}
}
}
在主导航向subnav移动鼠标时,为防止鼠标一从主导航离开,subnav立刻小时,所以通过setTimeout
延迟了300毫秒,在鼠标移动到subnav时,清除timer.
这样做的弊端就是在主导航之间滑动时,鼠标离开其中一块,移动到另一块区域时,timer
仍在继续,所以要在每一个onmouseover
中添加cleartimeout(timer)
(event || window.event).cancelBubble = true;
阻止冒泡事件发生,防止在触发子元素的onmouseover
事件时,会触发父元素的onmouseover
事件,使其执行了回调函数,所以此处阻止冒泡,就不能触发父元素的onmouseover
事件了
HTMLElement.offsetWidth
是一个只读属性,返回一个元素的布局宽度。offsetWidth是测量包含元素的边框(border)、水平线上的内边距(padding)、竖直方向滚动条(scrollbar)(如果存在的话)、以及CSS设置的宽度(width)的值。
HTMLElement.offsetLeft
是一个只读属性,返回当前元素左上角相对于 HTMLElement.offsetParent
节点的左边界偏移的像素值。
HTMLElement.offsetParent
指向的是离domElement最近的拥有position:relative/absolute属性的父级元素。若不存在,则指向 <body>元素。
判断显示区域就是判断二级导航显示位置,根据主导航的总宽度减父元素左边界的位置, 所得长度如果大于二级导航的宽度,则设置二级导航的left
为父元素的左边界的位置,否则,设置二级导航的right
为0, 二级导航为绝对定位
箭头的位置 父元素的左边界 减 二级导航的 左边界 加 50px ,这样就能使箭头处于父元素的中间位置