在上一篇《CSS+JavaScript 实现菜单功能》通过一个HTML页面简单的实现了菜单功能。但是实际开发当中,如果菜单栏有很多项,频繁的修改HTML,会很繁琐,也容易出错。
改进版本优化了这个问题,通过简单的Javascript代码就可以增加菜单。同时使得HTML页面非常简洁,只需要写2行代码即可!O(∩_∩)O
在上一篇《CSS+JavaScript 实现菜单功能》通过一个HTML页面简单的实现了菜单功能。但是实际开发当中,如果菜单栏有很多项,频繁的修改HTML,会很繁琐,也容易出错。
改进版本优化了这个问题,通过简单的Javascript代码就可以增加菜单。同时使得HTML页面非常简洁,只需要写2行代码即可!O(∩_∩)O
1.使用前提,在HTML页面中引入一个CSS文件,和一个JavaScript文件。如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>Menu</TITLE>
<link type="text/css" rel="stylesheet" href="menu.css">
</HEAD>
<BODY>
<div><script src="menu.js"></script></div>
</BODY>
</HTML>

引入CSS文件:<link type="text/css" rel="stylesheet" href="menu.css"> ,menu.css代码见后
引入JavaScript文件:<script src="menu.js"></script>
2.定义菜单代码如下:

if (document.getElementById)
{
var root = new Root();
var m1 = new Menu("File","alert(this.innerText);");
root.add(m1);
var m11 = new MenuItem("New");
m1.add(m11);
m1.add(new MenuItem("Open","alert('open file');"));
var m12 = new MenuItem("Save");
m1.add(m12);
m1.add(new MenuItem("Save As"));
m1.add(new MenuItem("Close"));
m1.add(new MenuItem(""));
var m2 = new Menu("Edit");
root.add(m2);
root.toString();
}

说明:
1) var root = new Root();
root.toString();
固定格式
2)声明菜单:
var m1 = new Menu("File","alert(this.innerText);");
菜单显示的名称为“File”,onclick事件为alert(this.innerText);
root.add(m1);
第一级菜单(即页面初始显示的菜单)放到root之下,通过add()方法
var m11 = new MenuItem("New"");
m1.add(m11);
声明“File”的子菜单“New”
m1.add(new MenuItem("Open","alert('open file');"));
声明“File”的子菜单“Open”
通过上面的代码即可完成菜单的添加功能。
代码文件:
<1> menu.cs

#menubar {
}{
font-family:verdana;
font-size:12px;
margin:1px;
}

#menubar li {
}{
float:left;
position:relative;
text-align:left;
}

/**//* each menu item style */

#menubar li a {
}{
border-style:none;
color:black;
display:block;
width:150px;
height:20px;
line-height:20px;
padding-left:10px;
text-decoration:none;
}

/**//* the first level menu which displays default */

#menubar .menuMain{
}{
border-color:#C0C0C0;
border-width:1px;
border-style:solid;
}

/**//* the first leve style when mouse on it */

#menubar li a:hover{
}{
background-color:#efefef;
text-decoration:underline;
}

/**//* the second level menu block style */

#menubar li ul{
}{
background-color:#efefef;
border-style:none;
display:none;
position:absolute;
top:20px;
left:-40px;
margin-top:2px;
width:150px;
}

/**//* the sub menu item style when mouse on it */

#menubar li ul li a:hover {
}{
text-decoration:underline;
padding-left:20px;
}

/**//* the third or more level menu block style */

#menubar li ul li ul {
}{
display:none;
position:absolute;
top:0px;
left:150px;
margin-top:0;
margin-left:0;
width:150px;
}

<2>menu.js

var MenuConfig =
{
defaultText : "Menu Item",
defaultAction : "javascript:void(0);" ,
defaultMenuCssStyle : "menuMain"
};


var MenuHandler =
{
idCounter : 0,
idPrefix : "menu-",

getId : function()
{ return this.idPrefix + this.idCounter++ ;},

insertHTMLBeforeEnd : function(node, sHTML)
{

if(node.insertAdjacentHTML != null)
{
node.insertAdjacentHTML('BeforeEnd',sHTML);
return;
}
var df; // DocumentFragment
var r = node.ownerDocument.createRange();
r.selectNodeContents(node);
r.collapse(false);
df = r.createContextualFragment(sHTML);
node.appendChild(df);
}
}


function displaySubMenu(li)
{
var subMenu = li.getElementsByTagName('ul')[0];
if(subMenu)
subMenu.style.display = 'block';
}


function hideSubMenu(li)
{
var subMenu = li.getElementsByTagName('ul')[0];
if(subMenu)
subMenu.style.display = 'none';
}



/**//******************************************
* Funciont Name: MenuAbstractNode
* Description: MenuAbstractNode class
* @param {String} pText
* @param {String} pAction
* @Return:
*******************************************/

function MenuAbstractNode(pText, pAction)
{
this.text = pText || MenuConfig.defaultText;
this.action = pAction || MenuConfig.defaultAction;
this.id = MenuHandler.getId();
this.childNodes = [];
}


MenuAbstractNode.prototype.add = function(node)
{
this.childNodes[this.childNodes.length] = node;
}


/**//******************************************
* Funciont Name: toString
* Description: generate HTML code
* @param
* @param
* @Return:
*******************************************/

MenuAbstractNode.prototype.toString = function()
{
var str = "<li id=\"" + this.id + "\" onmouseover=\"displaySubMenu(this)\" onmouseout=\"hideSubMenu(this)\"><a href=\"#\"";


if(this.type=="Menu")
{
str = str + " class=\"" + this.cssStyle + "\"";
}
str = str + " onclick=\""+this.action+"\">"+this.text+"</a>";
var sb = [];


for (var i = 0; i < this.childNodes.length; i++)
{
sb[i] = this.childNodes[i].toString();
}

if(sb.length>0)
{
str = str + "<ul>" + sb.join("") + "</ul>"
}

return str + "</li>" ;
}


/**//******************************************
* Funciont Name: Menu
* Description: Menu class
* @param {String} pText
* @param {String} pAction
* @param {String} pCssStyle
* @Return:
*******************************************/

function Menu(pText, pAction,pCssStyle)
{
this.base = MenuAbstractNode;
this.base(pText,pAction);
this.type = "Menu";
this.cssStyle = pCssStyle || MenuConfig.defaultMenuCssStyle;
}

Menu.prototype = new MenuAbstractNode;


/**//******************************************
* Funciont Name: MenuItem
* Description: MenuItem class
* @param {String} pText
* @param {String} pAction
* @Return:
*******************************************/

function MenuItem(pText, pAction)
{
this.base = MenuAbstractNode;
this.base(pText,pAction);
this.type = "MenuItem";
}

MenuItem.prototype = new MenuAbstractNode;



/**//******************************************
* Funciont Name: Root
* Description: Root class
* @Return:
*******************************************/

function Root()
{
this.id = "menubar";
this.childNodes=[];
}

Root.prototype = new MenuAbstractNode;


Root.prototype.toString = function()
{
document.write("<div id='menu'><ul id=\""+root.id+"\"> </ul> </div>");

for(var i=0; i<this.childNodes.length; i++)
{
MenuHandler.insertHTMLBeforeEnd(document.getElementById(root.id), this.childNodes[i].toString());
}
}


if (document.getElementById)
{
var root = new Root();
var m1 = new Menu("File","alert(this.innerText);");
root.add(m1);
var m11 = new MenuItem("New","alert(this.innerText);");
m1.add(m11);
m1.add(new MenuItem("Open","alert('open file');"));
var m12 = new MenuItem("Save");
m1.add(m12);
m1.add(new MenuItem("Save As"));
m1.add(new MenuItem("Close"));
m1.add(new MenuItem(""));
var m2 = new Menu("Edit");
root.add(m2);
var m22 = new MenuItem("Select All");
m2.add(m22);
m2.add(new MenuItem("Cut"));
m2.add(new MenuItem("Copy"));
m2.add(new MenuItem("paste"));
var m3 = new Menu("View");
var m33 = new MenuItem("View List");
m33.add(new MenuItem("Function List"));
m3.add(m33);
m3.add(new MenuItem("Tool Bar"));
root.add(m3);
root.toString();
}

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律