HTML5技术

使用JS开发桌面端应用程序NW.js-1-Menu菜单的使用小记 - 小小沧海

字号+ 作者:H5之家 来源:H5之家 2017-05-13 10:00 我要评论( )

使用JS开发桌面端应用程序NW.js-1-Menu菜单的使用小记 前言 本文主要内容为nw.js官方文档中没有提到,而在实际入手开发过程中才碰到的问题以及经验的汇总。 详情请查看官方文档: 1. MenuStrip与ContextMenu 在聊nwjs中的Menu之前先说下在传统window桌面端应

使用JS开发桌面端应用程序NW.js-1-Menu菜单的使用小记

前言

本文主要内容为nw.js官方文档中没有提到,而在实际入手开发过程中才碰到的问题以及经验的汇总。
详情请查看官方文档:

1. MenuStrip与ContextMenu

在聊nwjs中的Menu之前先说下在传统window桌面端应用开发中的两种常见的菜单。

windows中的MenuStrip

第一种:MenuStrip,菜单栏,通常在主窗体中的顶部,横向展示。如图:

windows中的ContextMenu

第二种:ContextMenu,上下文菜单,也就是右键菜单,关联某个元素,再某个元素上点击右键展现的菜单

nw.js中的nw.Menu

而在nw.js中,将windows系统的这两种菜单结合成一个对象:nw.Menu。
而区分的方法在于构造的配置对象的 type属性。

  • type属性设定为"menubar"则展现为MenuStrip行为,即窗体顶部菜单栏。
  • type属性设定为"contextmenu"则展现为右键菜单行为。默认为右键菜单
  • 官方说明:

    /** * Object that contains options to use while creation of nw.Menu. example: new nw.Menu(MenuOption) */ interface MenuOption { /** * {string} (Optional) two types are accepted by this method: "menubar" or "contextmenu". The value is set to "contextmenu" by default. */ type: string; } 2. nwjs中的多级菜单结构组成

    在nwjs中,有关菜单的只有两个对象,nw.Menu 和 nw.MenuItem。其中nw.Menu更多的功能与行为应该称之为 菜单集合。而 nw.MenuItem才是真正的 菜单项。

    用一张图来描述Menu和MenuItem对应的实际结构如图:


    如上图,红框为Menu,橙色为MenuItem,所有MenuItem的集合均为Menu,而MenuItem的子集的类型为Menu。

    接下来创建一个上图中的顶部菜单栏的代码示例:

    //创建一个顶部菜单栏,类型为:menubar var menuBar = new nw.Menu({ type: 'menubar' }); //创建一个一级菜单项-文件 var fileMenu = new nw.MenuItem({ label: "文件", }); //文件菜单的子菜单集合,类型为:contextmenu var fileMenuColl = new nw.Menu({ type: "contextmenu" }); //设定一级菜单文件的子菜单 fileMenu.submenu = fileMenuColl; // 创建一级菜单文件的子菜单:打开 var openMenu = new nw.MenuItem({ label: "打开", click: function () { console.log("打开"); }, }); //将打开菜单项 添加入文件子菜单集合中 fileMenuColl.append(openMenu); //创建一级菜单文件的子菜单:资源管理器 var explorerMenu = new nw.MenuItem({ label: "资源管理器", click: function () { console.log("资源管理器"); }, }); fileMenuColl.append(explorerMenu); //最后将一级菜单项文件 添加入菜单栏 menuBar.append(fileMenu); //设定窗体菜单栏 nw.Window.get().menu = menuBar;

    效果如下:

    3. MenItem必须最后再被Menu.append添加

    问题见代码示例。
    如将上述代码化简后:

    var menuBar = new nw.Menu({ type: 'menubar' }); var fileMenu = new nw.MenuItem({ label: "一级菜单" }); var fileMenuColl = new nw.Menu(); fileMenu.submenu = fileMenuColl; var openMenu = new nw.MenuItem({ label: "二级菜单" }); fileMenuColl.append(openMenu); menuBar.append(fileMenu);//关键,放在最后没问题,正常! win.menu = menuBar;

    效果如下:

    但是如果将menuBar.append(fileMenu)放在刚刚创建完fileMenu之后的话:

    var menuBar = new nw.Menu({ type: 'menubar' }); var fileMenu = new nw.MenuItem({ label: "一级菜单" }); //关键,创建fileMenu后立刻添加入菜单栏,会发生无法显示二级菜单的问题!!! menuBar.append(fileMenu); var fileMenuColl = new nw.Menu(); fileMenu.submenu = fileMenuColl; var openMenu = new nw.MenuItem({ label: "二级菜单" }); fileMenuColl.append(openMenu); win.menu = menuBar;

    问题:会出现二级菜单无法打开,只能看到一级菜单的问题。
    另外,如果再创建fileMenu时直接在构造函数的配置对象中制定了submenu的话,也可以避规此问题。

    私以为这个应该属于nwjs的一个bug或是一个缺陷。理论上来讲都属性引用类型,先append再新增,或先新增再append应该都是可以的。至少在C#的WinForm开发菜单时是这样的。

    原因不明。
    解决方案:只能在开发过程中严格遵守: 所有级别的菜单项,必须全部创建完成后最后再被父级append。

    4. nwjs顶部菜单栏不支持纯一级菜单

    在windows应用程序中:
    顶部菜单栏可以只有一级菜单,而没有其下属二级菜单。没有二级菜单也可实现相应各个点击事件等等,不强制要求必须有二级菜单。

    而在nwjs中:
    顶部菜单栏的纯一级菜单,即没有二级菜单项的一级菜单无法响应点击事件,其设定的click事件也是无效的,必须在二级菜单及更高级别的菜单中才可以响应点击事件。

    这就带来一个问题:
    在把纯windows应用程序使用nwjs重写时,那些纯一级菜单就必须折叠到二级菜单中,才能使用。

    另外:
    nwjs中只有顶部菜单受此影响,右键菜单不受此影响。

    这一点官方也有说明:

    To create a menubar, usually you have to create a 2-level menu and assign it to win.menu
    要创建一个窗体顶部菜单栏,必须使用二级菜单,并赋值给win.menu

     

    1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

    相关文章
    • 使用测试用例来约束自己的代码 - 陈宏鸿

      使用测试用例来约束自己的代码 - 陈宏鸿

      2017-05-09 14:00

    • VopSdk一个高逼格微信公众号开发SDK - deeround

      VopSdk一个高逼格微信公众号开发SDK - deeround

      2017-05-04 17:02

    • 【Vue 入门】使用 Vue2 开发一个展示项目列表的应用 - zhangjk

      【Vue 入门】使用 Vue2 开发一个展示项目列表的应用 - zhangjk

      2017-04-30 16:00

    • 对于Bootstrap的介绍以及如何使用 - novai-L

      对于Bootstrap的介绍以及如何使用 - novai-L

      2017-04-29 09:00

    网友点评