网页二级导航各种效果实现技巧

一般稍大点的网站都会运用二级导航甚至三级导航来将网站内容分门别类得更具体。二级导航的运用最为普遍,今天就主要来探讨二级导航的多种效果实现。以我个人以往的项目经验来看,我认为二级导航基本分为以下三种展现方式:

①     、水平通栏显示。即二级导航跳出主导航的宽度局限,而与页面同宽。
②     、水平同宽显示。即二级导航的宽度与主导航一致,表现为100%继承。
③     、垂直下拉显示。即二级导航垂直列出,宽度以其内容来定,且分别位于对应主导航下方。
而不管是哪种展现方式,都有一个共同点,就是二级导航都是在鼠标经过(滑过)对应的主导航时才显示出来,默认为隐藏。这个功能网上有多种JS实现方式,不过今天要跟大家分享的是不用JS,而只用CSS就可以实现且兼容各主流浏览器的一种方法。这种方法用到两个知识点::hover伪类选择器和position定位。
我们先写出通用结构代码来看:


  1. <ul class=”menu”>

  2. <li><a href=”#”>导航一</a>

  3. <ul class=”submenu”>

  4. <li><a href=”#”>子导航①</a></li>

  5. <li><a href=”#”>子导航②</a></li>

  6. </ul>

  7. </li>

  8. <li><a href=”#”>导航二</a></li>

  9. <li><a href=”#”>导航三</a></li>

  10. </ul>


分析一下:ul.submenu为二级导航,默认要隐藏;当鼠标经过“导航一”时要显示出来。很显然,我们要利用主导航的:hover伪类选择器。其次,所谓“隐藏”,就是在眼睛所见界面上是看不到的,那我们可以给它用position:absolute绝对定位到界面之外的地方,比如left:-999em,这个距离够远,所以就达成了“隐藏”的效果;那么显示的时候就将这个left值改为0就好了。定义了position:absolute绝对定位的元素是根据离其最近的定义了relative的外元素(即父级元素、祖父级元素等)容器发生位移的;如果没有这样一层外元素容器,那么它就会从文档流中脱出,根据文档(即body)的位置来进行位移。理解这点很重要,直接关系到区分三种方法之间的使用技巧。
首先为上面的结构代码写出简单的通用样式:

  1. * {margin:0; padding:0;}

  2. ul {list-style:none;}

  3. a {color:#fff; text-decoration:none;}

  4. body {font:14px/24px "微软雅黑";}


好了,下面我们依次来看三种展现方式的样式和效果:
第①种样式:

  1. .menu {width:316px; margin:0 auto; background:#000; height:24px; padding:0 2px;}

  2. .menu li {display:inline; padding:0 30px;}

  3. .submenu {position:absolute; width:100%; top:22px; background:#666; left:-999em; text-align:center;}

  4. .menu li:hover .submenu {left:0;}


鼠标经过效果:

第②种样式,只在第①种样式上加一处修改,如下红色部分:

  1. .menu {width:316px; margin:0 auto; background:#000; height:24px; padding:0 2px; position:relative;}


鼠标经过效果:

第③种样式,同样在第①种样式上做修改和添加,红色部分改动:

  1. .menu li {display:inline; padding:0 30px; position:relative;}

  2. .submenu li {display:block; padding:0; text-align:center;}


鼠标经过效果:

可以看出,三种方法区别不是很大,却有着全然不同的效果。能学会二级导航的这几种运用,那么触类旁通,三级导航也可同理用之。
另外,:hover伪类选择器兼容IE6需要引用一个hover.htc文件,将其放在CSS文件同目录下,调用方法是:body {behavior:url(../css/hover.htc);}
大家把下面这段代码贴到写字板另存为hover.htc文件就能用了。
<attach event="ondocumentready" handler="parseStylesheets" />
<script>
var csshoverReg = /(^|s)(([^a]([^ ]+)?)|(a([^#.][^ ]+)+)):(hover|active)/i,
currentSheet, doc = window.document, hoverEvents = [], activators = {
onhover:{on:'onmouseover', off:'onmouseout'},
onactive:{on:'onmousedown', off:'onmouseup'}
}
function parseStylesheets() {
if(!/MSIE (5|6)/.test(navigator.userAgent)) return;
window.attachEvent('onunload', unhookHoverEvents);
var sheets = doc.styleSheets, l = sheets.length;
for(var i=0; i<l; i++)
parseStylesheet(sheets[i]);
}
function parseStylesheet(sheet) {
if(sheet.imports) {
try {
var imports = sheet.imports, l = imports.length;
for(var i=0; i<l; i++) parseStylesheet(sheet.imports[i]);
} catch(securityException){}
}
try {
var rules = (currentSheet = sheet).rules, l = rules.length;
for(var j=0; j<l; j++) parseCSSRule(rules[j]);
} catch(securityException){}
}
function parseCSSRule(rule) {
var select = rule.selectorText, style = rule.style.cssText;
if(!csshoverReg.test(select) || !style) return;
var pseudo = select.replace(/[^:]+:([a-z-]+).*/i, 'on$1');
var newSelect = select.replace(/(.([a-z0-9_-]+):[a-z]+)|(:[a-z]+)/gi, '.$2' + pseudo);
var className = (/.([a-z0-9_-]*on(hover|active))/i).exec(newSelect)[1];
var affected = select.replace(/:(hover|active).*$/, '');
var elements = getElementsBySelect(affected);
if(elements.length == 0) return;
currentSheet.addRule(newSelect, style);
for(var i=0; i<elements.length; i++)
new HoverElement(elements[i], className, activators[pseudo]);
}
function HoverElement(node, className, events) {
if(!node.hovers) node.hovers = {};
if(node.hovers[className]) return;
node.hovers[className] = true;
hookHoverEvent(node, events.on, function() { node.className += ' ' + className; });
hookHoverEvent(node, events.off, function() { node.className = node.className.replace(new RegExp('s+'+className, 'g'),''); });
}
function hookHoverEvent(node, type, handler) {
node.attachEvent(type, handler);
hoverEvents[hoverEvents.length] = {
node:node, type:type, handler:handler
};
}
function unhookHoverEvents() {
for(var e,i=0; i<hoverEvents.length; i++) {
e = hoverEvents[i];
e.node.detachEvent(e.type, e.handler);
}
}
function getElementsBySelect(rule) {
var parts, nodes = [doc];
parts = rule.split(' ');
for(var i=0; i<parts.length; i++) {
nodes = getSelectedNodes(parts[i], nodes);
}    return nodes;
}
function getSelectedNodes(select, elements) {
var result, node, nodes = [];
var identify = (/#([a-z0-9_-]+)/i).exec(select);
if(identify) {
var element = doc.getElementById(identify[1]);
return element? [element]:nodes;
}
var classname = (/.([a-z0-9_-]+)/i).exec(select);
var tagName = select.replace(/(.|#|:)[a-z0-9_-]+/i, '');
var classReg = classname? new RegExp('b' + classname[1] + 'b'):false;
for(var i=0; i<elements.length; i++) {
result = tagName? elements[i].all.tags(tagName):elements[i].all;
for(var j=0; j<result.length; j++) {
node = result[j];
if(classReg && !classReg.test(node.className)) continue;
nodes[nodes.length] = node;
}
}
return nodes;
}
</script>

Need a translation service?

Please enter your personal details and we will contact you shortly

Words translated by CCJK

146,096,379

We are Certified

Our Client Satisfaction

rating for previous quarte

4.00

Over 95% of our clients recommend our language services to others

Copyright © CCJK Technologies Co., Ltd. 2000-2017. All rights reserved.
TOP