使用Popup窗口创建无限级Web页菜单(4)

前面的( 1),( 2),( 3)解决了popup创建Menu的主要技术问题后,现在开始具体的编码心里就有底多了,而且可以把精力集中在逻辑的处理上。当然还有一些UI的问题需要考虑,但都是HTML+CSS的小问题了。
    菜单的数据结构其实就是树,由于Menu及MenuItem有很多的自身属性,我们使用面向对象的方式来实现这个菜单。关于JavaScript面向对象的编成不是我讨论的主题,可以参考 蓝色经典上的文章来了解。我们一共实现两个类,一个Menu和一个MenuItem,Menu相当于一个集合,里面容纳n个MenuItem,其上除了菜单的属性外,主要是操作Collection的方法。类的定义如下:
function  Menu()
{
    
this .m_Items  =  [];                  //  菜单条目集合
     this .m_Popup  =   null ;             //  显示菜单的popup窗口
     this .m_Invalidate  =   false ;     //  是否失效标志
     this .m_Drawn  =   false ;           //  菜单是否已输出
     this .m_Opener  =   null ;            //  菜单的父窗口window对象
     this .m_ParentMenu  =   null ;   //  菜单的父菜单MenuItem对象
     this .m_ActiveItem  =   null ;     //  被激活(highlighting)的MenuItem
     this .m_ShowTimer  =   null ;    //  鼠标停留在有子菜单的条目上,子菜单显示延迟计时器
     this .m_Bounds  =   null ;           //  菜单的bounds
     this .m_ShowHeaderBlank  =   true //  是否显示MenuItem前的空白区域
     this .m_IsEventAttached  =   false ;     //  事件是否attached
     this .m_Id  =  __MenuCache__.NewId();  //  或取菜单对象的唯一标识
    __MenuCache__[ this .m_Id]  =   this //  把菜单放入__MenuCache__

    
this .toString  =   function ()
    {
        
return  '[class Menu]';
    };
}

    菜单类的方法有:
Menu.prototype.Add  =   function (mi)
{
    
//  添加菜单条目到菜单中
};

Menu.prototype.AddAt 
=   function (mi, index)
{
    
//  把菜单条目添加到指定的数组索引上
};

Menu.prototype.AddSeparator 
=   function ()
{
    
//  添加一个Separator Item,就是我们在window菜单里的"-"
};

Menu.prototype.Remove 
=   function (mi)
{
    
//  删除菜单中的一个菜单条目
};

Menu.prototype.Contains 
=   function (menu)
{
    
//  判断已构建的菜单中是否已包含了menu
};

Menu.prototype.Render 
=   function ()
{
    
//  生成菜单UI显示需要的DHTML
};

Menu.prototype.__generatePaddingTR 
=   function (doc)
{
    
//  为了美化菜单UI生成的一个TR element
};

Menu.prototype.AttachEvents 
=   function (menu)
{
    
//  attach事件处理函数到菜单事件上
};

Menu.prototype.ActiveItem 
=   function (evt)
{
    
//  处理菜单itme被Active后的UI和动作等
};

Menu.prototype.Hide 
=   function ()
{
    
//  隐藏菜单
};

Menu.prototype.Keydown 
=   function (evt)
{
    
//  处理键盘按键
};

Menu.prototype.Click 
=   function ()
{
    
//  执行菜单被click
};

Menu.prototype.ResumeItem 
=   function (evt)
{
    
//  恢复菜单,取消active和恢复UI
};

Menu.prototype.__resumeItem 
=   function ()
{
    
//  执行UI恢复
};

Menu.prototype.__resumeAll 
=   function ()
{
    
//  执行批量UI恢复
};

Menu.prototype.__activeItem 
=   function ()
{
    
//  执行UI激活
};

Menu.prototype.HasSubMenuExpanded 
=   function ()
{
    
//  判断菜单是否有展开的submenu
};

Menu.prototype.__isEllipsis 
=   function (menuObj, menuHtml)
{
    
//  在菜单item的text过长时将截断并显示""
};

Menu.prototype.Show 
=   function (evt)
{
    
//  显示菜单
};

Menu.prototype.InnerShow 
=   function ()
{
    
//  显示submenu,用于菜单内部触发的菜单显示
};

Menu.prototype.__show 
=   function (miObj)
{
    
//  执行菜单显示
};

Menu.prototype.FadeinEffect 
=   function (effect)
{
    
//  菜单显示式的特效,是用filter来实现,只在Show菜的时候调用
};

    类MenuItem比Menu类简单很多,定义如下:
function MenuItem(text, action, icon, shortcut, menu)
{
    
this.m_Text = text;                // 菜单文本
    this.m_Action = action;        // 菜单条目被触发时执行的函数
    this.m_Icon = icon;               // 菜单条目前的图标路径
    this.m_ChildMenu = menu; // 子菜单,类型为Menu对象
    this.m_Menu = null;              // 本菜单条目所在的菜单对象实例
    this.m_ShortCut = shortcut; // 快捷方式(保留,未实现)
    this.m_Disabled = false;      
    
this.m_Mnemonic = null;
    
this.m_Tooltip = null;
    
this.m_Attributes = [];          // 附加属性集合,由SetAttribute设置
    this.m_Id = __MenuCache__.NewId();
    __MenuCache__[
this.m_Id] = this;

    
this.toString = function()
    
{
        
return '[class MenuItem]';
    }
;
}

    MenuItem类的方法如下:
MenuItem.prototype.Contains  =   function (menu)
{
    
//  子菜单中是否已添加menu
};

MenuItem.prototype.SetAttribute 
=   function (key, value)
{
    
//  设置用户定义的属性
};

MenuItem.prototype.GetAttribute 
=   function (key)
{
    
//  或取用户定义的属性
};

MenuItem.prototype.Invalidate 
=   function ()
{
    
//  失效
};

MenuItem.prototype.IsSeparator 
=   function ()
{
    
//  判断MenuItem是否为Separator,就是其m_Text == '-'
}

MenuItem.prototype.Render 
=   function ()
{
    
//  生成菜单UI的DHTML
};

MenuItem.prototype.SetBorderColor 
=   function (miHtml, width, borderColor)
{
    
//  设置菜单条目的边框颜色
};
    "__"开头的方法是内部方法,不提供给类外使用。变量命名规则m_开头的是类属性变量,Obj结尾的是菜单类对象,和它相对的是Html结尾的,使菜单的HTML元素对象,常见的是menuObj、menuHtml、miObj和miHTML。

    Menu类中最重要的方法是:
Menu.prototype.AttachEvents  =   function (menu)
Menu.prototype.ActiveItem 
=   function (evt)
Menu.prototype.HasSubMenuExpanded 
=   function ()
Menu.prototype.Show 
=   function (evt)
Menu.prototype.InnerShow 
=   function ()
Menu.prototype.__show 
=   function (miObj)
    MenuItem主要是处理UI显示,没有太重要的方法。  

 未完
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值