CSS+JavaScript 实现菜单功能--改进版
马嘉楠   2008-12-08
 
在上一篇《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();     
} 

 
 
 
 马嘉楠
jianan.ma@gmail.com 
	posted on 2008-12-12 20:10 
马嘉楠 阅读(2461) 
评论(4)  编辑  收藏  所属分类: 
SoureCode 、
Java Script