网站开发的基本过程,wordpress 标点排版,公司网站建设ihanshi,微信小程序怎么做活动代码框架在(4)里面已经全部列出来了#xff0c;现在工作就是按流程把他们完成。本来实现一个prototype的Menu菜单类只需要最多300行代码#xff0c;可是后来做了一些操作习惯支持和UI显示上的优化后#xff0c;代码猛增到了1000多行。不过final版本看起来确实比土不拉叽的pr…代码框架在(4)里面已经全部列出来了现在工作就是按流程把他们完成。本来实现一个prototype的Menu菜单类只需要最多300行代码可是后来做了一些操作习惯支持和UI显示上的优化后代码猛增到了1000多行。不过final版本看起来确实比土不拉叽的prototype强很多哦。 为了比较直观的说明代码的作用我就从菜单的显示开始说。要显示一个菜单显必须构建一个菜单的实例实例构建的完整代码如下 div oncontextmenureturn ShowContextMenu(this); stylewidth: 200; height: 200; border: solid 1px blue; table width100% height100% border0 tr td valignmiddle aligncenter right click me /td /tr /table /div script languagejavascript function ShowContextMenu(elmt) { if ( !elmt.contextMenu ) { elmt.contextMenu CreateContextMenu(); } var win window; elmt.contextMenu.Show(win); return false; } CreateMenu#region CreateMenu function CreateContextMenu() { var menu new Menu(); for ( var i1 ; i 6 ; i ) { var mi new MenuItem(Menu Item 1- i, Alert); menu.Add(mi); } var submenu new Menu(); for ( var i1 ; i 5 ; i ) { var mi new MenuItem(Menu Item 3- i, Alert); submenu.Add(mi); } var submenu2 new Menu(); submenu2.Add(new MenuItem(Menu Item 2-1, null, null, null, submenu)); var mi2 new MenuItem(Menu Item 1-6, Alert, images/paste.small.png, null, submenu2); menu.AddAt(mi2, 2); return menu; } #endregion /script 生成的Context Menu效果 这是完全手工添加菜单条目生成的一个Context Menu最后会完成一个自动解析菜单数据来生成菜单的方法。 我们现在来看这个Menu.prototype.Show(win)方法这是菜单的第一级显示时的方法它是由用户来调用的因为菜单需要定位于用户给定位置(ContextMenu的用户给定位置就是鼠标点击的位置)。在菜单显示出第一级后后续的子菜单的显示都是在Menu类内部来处理的子菜单位置是相对于parent menu后续逻辑就都封装在Menu类内部了。Show()方法代码如下 Menu.prototype.Show function(win) { if ( !win ) { return; } var menuObj this; menuObj.m_Opener win; menuObj.__resumeItem(); var win menuObj.m_Opener; var popup, popwin, popdoc; // 判断菜单的容器popup是否建立 if ( !menuObj.m_Popup ) { popup win.createPopup(); popup.document.body.bgColor windowtext; popup.document.body.style.backgroundColor window; menuObj.m_Popup popup; } else { popup menuObj.m_Popup; menuObj.__resumeAll(); } popdoc popup.document; popwin popdoc.parentWindow; // 判断是否需要重绘菜单的内容 if ( menuObj.m_Invalidate || !menuObj.m_Drawn ) { popdoc.body.innerHTML menuObj.Render().outerHTML; // popdoc.body.appendChild(menuObj.Render()); menuObj.m_Invalidate false; menuObj.m_Drawn true; } // 获取菜单的主table(菜单是使用table来实现的) var menuHtml popup.document.getElementById(menu); // 这个show只是为了测量菜单的bounds而调用的 popup.show(0, 0, 1, 1); var w popdoc.body.scrollWidth; // 判断菜单条目的Text的显示宽度是否在许可范围内 // 如果超出许可范围则ellipsis处理并返回新的MenuItem的width w this.__isEllipsis(this, menuHtml); var h popdoc.body.scrollHeight; var x win.event.clientX win.screenLeft; var y win.event.clientY win.screenTop; popup.show(x, y, w, h); // 菜单的显示特效使用filter实现的 this.FadeinEffect(Menu.Attributes.ShowMenuEffect); menuObj.m_Bounds { top: x, left: y, width: menuHtml.offsetWidth, height: menuHtml.offsetHeight }; // 把菜单操作的事件attach到菜单上鼠标和键盘操作等 menuObj.AttachEvents(menuHtml); }; 上面注解应该都比较清楚了只是这个popup.show(0, 0, 1, 1);比较有意思哈当我们向popup里添加好了菜单的HTML元素后我们发现在popup没有显示过之前是根本取不到构成Menu UI的那个Table element的bounds信息的。这里show上一下后就是为了让IE算出其bounds信息然后再使用实际的bounds信息show菜单。这算一个小hack吧也是这个Menu中比较有效率的地方因为除了这个show(0, 0, 1,1)就在没有计算菜单bounds的地方了当然也用不着了。然而为什么又没有把bounds计算也做成lazy load象popup的生成那样呢是因为用户可能在菜单显示后修改IE的字体大小(比如按住Ctrl再滚动鼠标滚轮)这样保证了再次显示菜单时能修正菜单的实际bounds。而后面把menu的bounds存了起来是为了在显示子菜单时方便判断其默认向右展开空间是否足够如果不够宽则从parent menu左侧展开。 to be continued ... 转载于:https://www.cnblogs.com/birdshome/archive/2004/12/17/78200.html