最近做个项目需要使用一个菜单,下拉菜单那种,无奈发现菜单项太多,但项目时间很紧,从网上找了些菜单的实现,都不是很理想,主要是菜单项目太多了,而且总是那么多不自由,所以决定自己写个能够自由灵活使用的菜单,并且能容纳下尽可能多的菜单项。要容纳很多的菜单项(比如上百个,不能用做成树),不能做成纯粹下拉的,只能做成矩阵排列那种了。但同时为了灵活,所以采用DIV才装菜单项,可以自由做成自己想要的样子。其中JS代码如下:
将以上JS做成一个JS文件链接进HTML文件中,一个DEMO如下:
主要的灵活之处在于没有写死CSS,你可以自己配置CSS,想要什么效果都可以,可以做并排菜单,或者下拉的,或者其它你想要的。
- function Menu(menu){
- this.isIE = !!(window.attachEvent &&navigator.userAgent.indexOf('Opera') === -1);//判断是否是IE
- this.y = function(e){
- var offset=e.offsetTop;
- if(e.offsetParent!=null) offset+=this.y(e.offsetParent);
- return offset;
- }
- this.x = function(e){
- var offset=e.offsetLeft;
- if(e.offsetParent!=null) offset+=this.x(e.offsetParent);
- return offset;
- }
- this.$ = function(id){
- return document.getElementById(id);
- }
- this.$$ = function(obj,name){
- var rs = new Array();
- var childNodes = obj.childNodes;
- for(var i = 0 ;i<childNodes.length;i++){
- if(childNodes[i].nodeName == name){
- rs.push(childNodes[i]);
- }
- }
- return rs;
- }
- this.root = this.$(menu);
- this.init();
- }
- Menu.prototype.init = function(){
- this.bind(this.root);
- }
- Menu.prototype.bind = function(root){
- var liNodes = this.$$(root,'LI');
- for(var i = 0;i<liNodes.length;i++){
- var liNode = liNodes[i];
- if(liNode.style.display==''||liNode.style.display=='none'){
- if(this.isIE){
- liNode.style.display = 'inline';
- }
- else {
- liNode.style.display = 'inline-block';
- }
- }
- var divs = this.$$(liNode,'DIV');
- for(var j=0;j<divs.length;j++){
- var div = divs[j];
- div.style.display = 'none';
- if(div.style.width==''){
- div.style.maxWidth = this.root.style.width;
- }
- div.style.position = 'absolute';
- if(this.isIE){
- div.style.left = this.x(liNode);
- div.style.top = this.y(liNode) + liNode.offsetHeight;
- }
- var uls = this.$$(div,'UL');
- for(var k =0;k<uls.length;k++){
- this.bind(uls[k]);
- }
- }
- liNode.$$ = function(name){
- var rs = new Array();
- var childNodes = this.childNodes;
- for(var i = 0 ;i<childNodes.length;i++){
- if(childNodes[i].nodeName == name){
- rs.push(childNodes[i]);
- }
- }
- return rs;
- }
- liNode.onmouseover = function (){
- var ds = this.$$('DIV');
- for(var j=0;j<ds.length;j++){
- var div = ds[j];
- div.style.display = 'block';
- }
- }
- liNode.onmouseout = function (){
- var ds = this.$$('DIV');
- for(var j=0;j<ds.length;j++){
- var div = ds[j];
- div.style.display = 'none';
- }
- }
- }
- }
function Menu(menu){
this.isIE = !!(window.attachEvent &&navigator.userAgent.indexOf('Opera') === -1);//判断是否是IE
this.y = function(e){
var offset=e.offsetTop;
if(e.offsetParent!=null) offset+=this.y(e.offsetParent);
return offset;
}
this.x = function(e){
var offset=e.offsetLeft;
if(e.offsetParent!=null) offset+=this.x(e.offsetParent);
return offset;
}
this.$ = function(id){
return document.getElementById(id);
}
this.$$ = function(obj,name){
var rs = new Array();
var childNodes = obj.childNodes;
for(var i = 0 ;i<childNodes.length;i++){
if(childNodes[i].nodeName == name){
rs.push(childNodes[i]);
}
}
return rs;
}
this.root = this.$(menu);
this.init();
}
Menu.prototype.init = function(){
this.bind(this.root);
}
Menu.prototype.bind = function(root){
var liNodes = this.$$(root,'LI');
for(var i = 0;i<liNodes.length;i++){
var liNode = liNodes[i];
if(liNode.style.display==''||liNode.style.display=='none'){
if(this.isIE){
liNode.style.display = 'inline';
}
else {
liNode.style.display = 'inline-block';
}
}
var divs = this.$$(liNode,'DIV');
for(var j=0;j<divs.length;j++){
var div = divs[j];
div.style.display = 'none';
if(div.style.width==''){
div.style.maxWidth = this.root.style.width;
}
div.style.position = 'absolute';
if(this.isIE){
div.style.left = this.x(liNode);
div.style.top = this.y(liNode) + liNode.offsetHeight;
}
var uls = this.$$(div,'UL');
for(var k =0;k<uls.length;k++){
this.bind(uls[k]);
}
}
liNode.$$ = function(name){
var rs = new Array();
var childNodes = this.childNodes;
for(var i = 0 ;i<childNodes.length;i++){
if(childNodes[i].nodeName == name){
rs.push(childNodes[i]);
}
}
return rs;
}
liNode.onmouseover = function (){
var ds = this.$$('DIV');
for(var j=0;j<ds.length;j++){
var div = ds[j];
div.style.display = 'block';
}
}
liNode.onmouseout = function (){
var ds = this.$$('DIV');
for(var j=0;j<ds.length;j++){
var div = ds[j];
div.style.display = 'none';
}
}
}
}
将以上JS做成一个JS文件链接进HTML文件中,一个DEMO如下:
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>无标题文档</title>
- <script src="Menu.js" type="text/javascript"></script>
- </head>
- <body>
- <ul id="nav" style="width:600px;">
- <li style="background-color:#F11111;">
- <span>菜单一</span>
- <div style="background-color:#666;">菜单内容菜单内容菜单内容一菜单内容菜单内容菜单内容一菜单内容菜单内容菜单内容一菜单内容菜单内容菜单内容一</div>
- </li>
- <li style="background-color:#CCC;">
- <span>菜单二</span>
- <div style="background-color:#666;">
- <ul>
- <li style="display:inherit">二级菜单</li>
- <li style="display:inherit">二级菜单</li>
- <li style="display:inherit">二级菜单</li>
- <li style="display:inherit">二级菜单</li>
- <li style="display:inherit">
- <span>二级菜单</span>
- <div style="background-color:#666; width:300px;">
- <ul>
- <li >三级菜单</li>
- <li >三级菜单</li>
- <li >三级菜单</li>
- <li >三级菜单</li>
- <li >三级菜单</li>
- </ul>
- </div>
- </li>
- </ul>
- </div>
- </li>
- <li style="background-color:#CCC;">
- <span>菜单三</span>
- <div style="background-color:#666;">菜单内容菜单内容菜单内容三</div>
- </li>
- </ul>
- <script language="javascript">
- new Menu('nav');
- </script>
- </body>
- </html>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<script src="Menu.js" type="text/javascript"></script>
</head>
<body>
<ul id="nav" style="width:600px;">
<li style="background-color:#F11111;">
<span>菜单一</span>
<div style="background-color:#666;">菜单内容菜单内容菜单内容一菜单内容菜单内容菜单内容一菜单内容菜单内容菜单内容一菜单内容菜单内容菜单内容一</div>
</li>
<li style="background-color:#CCC;">
<span>菜单二</span>
<div style="background-color:#666;">
<ul>
<li style="display:inherit">二级菜单</li>
<li style="display:inherit">二级菜单</li>
<li style="display:inherit">二级菜单</li>
<li style="display:inherit">二级菜单</li>
<li style="display:inherit">
<span>二级菜单</span>
<div style="background-color:#666; width:300px;">
<ul>
<li >三级菜单</li>
<li >三级菜单</li>
<li >三级菜单</li>
<li >三级菜单</li>
<li >三级菜单</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
<li style="background-color:#CCC;">
<span>菜单三</span>
<div style="background-color:#666;">菜单内容菜单内容菜单内容三</div>
</li>
</ul>
<script language="javascript">
new Menu('nav');
</script>
</body>
</html>
主要的灵活之处在于没有写死CSS,你可以自己配置CSS,想要什么效果都可以,可以做并排菜单,或者下拉的,或者其它你想要的。