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

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

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

    菜单类的方法有:
None.gifMenu.prototype.Add =  function(mi)
None.gif{
None.gif     //  添加菜单条目到菜单中
None.gif
};
None.gif
None.gifMenu.prototype.AddAt =  function(mi, index)
None.gif{
None.gif     //  把菜单条目添加到指定的数组索引上
None.gif
};
None.gif
None.gifMenu.prototype.AddSeparator =  function()
None.gif{
None.gif     //  添加一个Separator Item,就是我们在window菜单里的"-"
None.gif
};
None.gif
None.gifMenu.prototype.Remove =  function(mi)
None.gif{
None.gif     //  删除菜单中的一个菜单条目
None.gif
};
None.gif
None.gifMenu.prototype.Contains =  function(menu)
None.gif{
None.gif     //  判断已构建的菜单中是否已包含了menu
None.gif
};
None.gif
None.gifMenu.prototype.Render =  function()
None.gif{
None.gif     //  生成菜单UI显示需要的DHTML
None.gif
};
None.gif
None.gifMenu.prototype.__generatePaddingTR =  function(doc)
None.gif{
None.gif     //  为了美化菜单UI生成的一个TR element
None.gif
};
None.gif
None.gifMenu.prototype.AttachEvents =  function(menu)
None.gif{
None.gif     //  attach事件处理函数到菜单事件上
None.gif
};
None.gif
None.gifMenu.prototype.ActiveItem =  function(evt)
None.gif{
None.gif     //  处理菜单itme被Active后的UI和动作等
None.gif
};
None.gif
None.gifMenu.prototype.Hide =  function()
None.gif{
None.gif     //  隐藏菜单
None.gif
};
None.gif
None.gifMenu.prototype.Keydown =  function(evt)
None.gif{
None.gif     //  处理键盘按键
None.gif
};
None.gif
None.gifMenu.prototype.Click =  function()
None.gif{
None.gif     //  执行菜单被click
None.gif
};
None.gif
None.gifMenu.prototype.ResumeItem =  function(evt)
None.gif{
None.gif     //  恢复菜单,取消active和恢复UI
None.gif
};
None.gif
None.gifMenu.prototype.__resumeItem =  function()
None.gif{
None.gif     //  执行UI恢复
None.gif
};
None.gif
None.gifMenu.prototype.__resumeAll =  function()
None.gif{
None.gif     //  执行批量UI恢复
None.gif
};
None.gif
None.gifMenu.prototype.__activeItem =  function()
None.gif{
None.gif     //  执行UI激活
None.gif
};
None.gif
None.gifMenu.prototype.HasSubMenuExpanded =  function()
None.gif{
None.gif     //  判断菜单是否有展开的submenu
None.gif
};
None.gif
None.gifMenu.prototype.__isEllipsis =  function(menuObj, menuHtml)
None.gif{
None.gif     //  在菜单item的text过长时将截断并显示"dot.gif"
None.gif
};
None.gif
None.gifMenu.prototype.Show =  function(evt)
None.gif{
None.gif     //  显示菜单
None.gif
};
None.gif
None.gifMenu.prototype.InnerShow =  function()
None.gif{
None.gif     //  显示submenu,用于菜单内部触发的菜单显示
None.gif
};
None.gif
None.gifMenu.prototype.__show =  function(miObj)
None.gif{
None.gif     //  执行菜单显示
None.gif
};
None.gif
None.gifMenu.prototype.FadeinEffect =  function(effect)
None.gif{
None.gif     //  菜单显示式的特效,是用filter来实现,只在Show菜的时候调用
None.gif
};

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

    MenuItem类的方法如下:
None.gifMenuItem.prototype.Contains =  function(menu)
None.gif{
None.gif     //  子菜单中是否已添加menu
None.gif
};
None.gif
None.gifMenuItem.prototype.SetAttribute =  function(key, value)
None.gif{
None.gif     //  设置用户定义的属性
None.gif
};
None.gif
None.gifMenuItem.prototype.GetAttribute =  function(key)
None.gif{
None.gif     //  或取用户定义的属性
None.gif
};
None.gif
None.gifMenuItem.prototype.Invalidate =  function()
None.gif{
None.gif     //  失效
None.gif
};
None.gif
None.gifMenuItem.prototype.IsSeparator =  function()
None.gif{
None.gif     //  判断MenuItem是否为Separator,就是其m_Text == '-'
None.gif
}
None.gif
None.gifMenuItem.prototype.Render =  function()
None.gif{
None.gif     //  生成菜单UI的DHTML
None.gif
};
None.gif
None.gifMenuItem.prototype.SetBorderColor =  function(miHtml, width, borderColor)
None.gif{
None.gif     //  设置菜单条目的边框颜色
None.gif
};
    "__"开头的方法是内部方法,不提供给类外使用。变量命名规则m_开头的是类属性变量,Obj结尾的是菜单类对象,和它相对的是Html结尾的,使菜单的HTML元素对象,常见的是menuObj、menuHtml、miObj和miHTML。

    Menu类中最重要的方法是:
None.gifMenu.prototype.AttachEvents =  function(menu)
None.gifMenu.prototype.ActiveItem =  function(evt)
None.gifMenu.prototype.HasSubMenuExpanded =  function()
None.gifMenu.prototype.Show =  function(evt)
None.gifMenu.prototype.InnerShow =  function()
None.gifMenu.prototype.__show =  function(miObj) None.gif

    MenuItem主要是处理UI显示,没有太重要的方法。 


本文转自博客园鸟食轩的博客,原文链接:http://www.cnblogs.com/birdshome/,如需转载请自行联系原博主。  

目录
相关文章
|
存储 IDE 前端开发
SpringBoot2.x系列教程02--新纪元之SpringBoot创建Web项目的常用方式
前言 在上一章节中,壹哥 给大家介绍了SpringBoot的优缺点,并重点介绍了其”约定大于配置“的思想,你现在还能记得吗? 而且上文中,壹哥 说我们创建SpringBoot项目有3种方式,我们已经学习了第一种创建项目的方式了,接下来还有另外两种创建项目的方式,这两种方式该怎么创建项目呢?今天 壹哥 就把剩余的两种方式也一股脑都抖搂给大家吧。 一. 以官网模板方式创建Web项目(了解) 首先 壹哥 给大家介绍第2种创建Web项目的方式,对于这种方式大家仅做了解即可,其原理与第一种以Spring Initializr创建项目的方式一样。 1. 在spring.io官网下载模板构建项目 首先我们
322 0
|
存储 前端开发 JavaScript
【一步步一起学DApp开发】(四)web3.js 基本使用 | 连接geth | 创建web客户端
【一步步一起学DApp开发】(四)web3.js 基本使用 | 连接geth | 创建web客户端
601 0
|
JSON JavaScript 中间件
【node.js从入门到精通】使用express创建web服务器,路由,进行中间件的创建链接路由及其他中间件
【node.js从入门到精通】使用express创建web服务器,路由,进行中间件的创建链接路由及其他中间件
197 1
【node.js从入门到精通】使用express创建web服务器,路由,进行中间件的创建链接路由及其他中间件
|
NoSQL MongoDB 数据库
MongoDB v4.4.6安装、创建服务及Web客户端访问MongoDB详解
MongoDB v4.4.6安装、创建服务及Web客户端访问MongoDB详解
277 0
MongoDB v4.4.6安装、创建服务及Web客户端访问MongoDB详解
|
数据采集 Go
Go Web编程实战(9)----创建客户端
Go Web编程实战(9)----创建客户端
140 1
|
Java Go
Go Web编程实战(8)----创建HTTP与HTTPS服务器端
Go Web编程实战(8)----创建HTTP与HTTPS服务器端
188 0
Go Web编程实战(8)----创建HTTP与HTTPS服务器端
|
JavaScript
【Node.JS 】创建基本的web服务器
【Node.JS 】创建基本的web服务器
158 0
【Node.JS 】创建基本的web服务器
|
Java Maven
IDEA2022版本创建maven web项目(两种方式)
创建maven web项目有两种方式,一种是使用骨架方式,一种是不使用骨架的方式
693 1
IDEA2022版本创建maven web项目(两种方式)
|
Web App开发 XML 开发框架
WebAPI学习(一)——创建Web API程序
WebAPI学习(一)——创建Web API程序
248 0
|
JavaScript 前端开发
Node.js 创建并封装静态 WEB 服务器
Node.js 创建并封装静态 WEB 服务器
122 0
Node.js 创建并封装静态 WEB 服务器

热门文章

最新文章