文/玄魂html
目录html5
node-webkit教程(6)Native UI API 之Menu(菜单)node
前言ios
6.1 Menu 概述git
6.2 menu apigithub
6.2.1 new Menu([option])web
6.2.2 Menu.itemsjson
6.2.3 Menu.items.lengthubuntu
6.2.4 Menu.items[i]windows
6.2.5 Menu.append(MenuItem item)
6.2.6 Menu.insert(MenuItem item, int i)
6.2.7 Menu.remove(MenuItem item)
6.2.8 Menu.removeAt(int i)
6.2.9 Menu.item[x].click
6.2.10 Menu.popup(int x, int y)
6.3 建立右键菜单
6.4 MenuItem
6.4.1 new MenuItem(option)
6.4.2 MenuItem.type
6.4.3 MenuItem.label
6.4.4 MenuItem.icon
6.4.5 MenuItem.tooltip
6.4.6 MenuItem.checked
6.4.7 MenuItem.enabled
6.4.8 MenuItem.submenu
6.4.9 MenuItem.click
6.6 小结
几个月前,要开发一个简易的展现应用,要求支持离线播放(桌面应用)和在线播放(web应用)。
当时第一想到的是flex,同一套代码(或者只需少许的更改)就能够同时运行在桌面和浏览器上。因为不少展示效果要全新开发,我想到了impress.js(https://github.com/bartaz/impress.js/)。若是选择impress.js,就意味着要将html5做为桌面应用,当时想到要封装webkit,可是本人对这方面也不是很熟悉,时间也颇有限,就又沿着这个方向搜索,找到了node-webkit(https://github.com/rogerwang/node-webkit)。
node-webkit解决了我经过html和js来编写桌面应用的难题。
至于node-webkit的定义,按照做者的说法:
“ 基于node.js和chromium的应用程序实时运行环境,可运行经过HTML(5)、CSS(3)、Javascript来编写的本地应用程序。node.js和webkit的结合体,webkit提供DOM操做,node.js提供本地化操做;且将两者的context彻底整合,可在HTML代码中直接使用node.js的API。”
Menu API 提供的是本地化的窗口菜单,即windows下常说的菜单栏,定义的菜单显示在本地化(native)window上,而不是属于DOM文档。参考:node-webkit学习(4)Native UI API 之window(http://www.xuanhun521.com/Blog/2014/4/14/node-webkit%E5%AD%A6%E4%B9%A04native-ui-api-%E4%B9%8Bwindow)
Menu分为两种,window菜单和上下文(右键)菜单(context menu)。
建立menu对象使用构造函数Menu([option]),如:
// Load native UI library
var gui = require('nw.gui');
// Create an empty menu
var menu = new gui.Menu();
不带参数构造的menu属于context menu,若是想建立window menu,使用以下方式:
var your_menu = new gui.Menu({ type: 'menubar' });
将window menu直接赋值给window 对象的menu属性便可生效。
gui.Window.get().menu = your_menu;
建立menuDemo.html和package.json。menuDemo.html代码以下:
<html>
<head>
<title>menuDemo</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body >
<h1>menu api 测试</h1>
<script>
// Load native UI library
var gui = require('nw.gui');
var win = gui.Window.get();
//建立window menu
var windowMenu = new gui.Menu({ type: 'menubar' });
var windowSubmenu = new gui.Menu();
var subMenuItem = new gui.MenuItem({ label: '子菜单项' });
windowSubmenu.append(subMenuItem);
windowMenu.append(
new gui.MenuItem({ label: '子菜单', submenu: windowSubmenu })
);
win.menu = windowMenu;
// Create an empty menu
var menu = new gui.Menu();
// Add some items
menu.append(new gui.MenuItem({ label: 'Item A' }));
menu.append(new gui.MenuItem({ label: 'Item B' }));
menu.append(new gui.MenuItem({ type: 'separator' }));
menu.append(new gui.MenuItem({ label: 'Item C' }));
// Remove one item
menu.removeAt(1);
// Popup as context menu
menu.popup(10, 10);
// Iterate menu's items
for (var i = 0; i < menu.items.length; ++i) {
var element = document.createElement('div');
element.appendChild(document.createTextNode(menu.items[i].label));
document.body.appendChild(element);
}
</script>
</body>
</html>
package.json文件内容以下:
{
"name": "menu-demo",
"main": "menuDemo.html",
"nodejs":true,
"width":100,
"height":200,
"window": {
"title": "MenuDemo",
"toolbar": true,
"width": 800,
"height": 600,
"resizable":true,
"show_in_taskbar":true,
"frame":true,
"kiosk":false
},
"webkit":{
"plugin":true
}
}
运行结果以下:
构造函数,见上文。
获取该Menu下全部的MenuItem对象,返回结果为数组。上文中的例子,有这样的代码:
for (var i = 0; i < menu.items.length; ++i) {
var element = document.createElement('div');
element.appendChild(document.createTextNode(menu.items[i].label));
document.body.appendChild(element);
}
上面的代码经过menu.items获取全部menuitem对象,遍历输出label。这里须要注意的是,并非全部的menuitem都有label属性。
menuitem的个数。参加上文demo。
经过索引返回一个menuitem对象。
向当前菜单中添加一个menuitem对象,该对象在整个menuitem集合的尾部。
在menuitem集合的指定位置插入一个menuitem对象。
从menuitem集合中移除一个menuitem对象。
删除menuitem集合中指定位置的menuitem对象。
设置menuitem集合中指定位置的menuitem对象的click事件,在menuDemo.html中添加以下代码:
menu.items[0].click = function() {
var element = document.createElement('div');
element.appendChild(document.createTextNode(‘我被点击了’));
document.body.appendChild(element);
};
结果以下:
点击前
点击后
在当前窗口的指定位置弹窗菜单。示例代码见上文。
建立右键菜单,须要在页面监听contextmenu
事件,而后控制弹出菜单。修改以前的菜单弹出代码:
document.body.addEventListener('contextmenu', function (ev) {
ev.preventDefault();
menu.popup(10, 10);
return false;
});
启动时页面以下:
单击右键后,界面显示菜单:
从上面的叙述中,咱们已经知道,menu和menuitem的一块儿组合,才能最终组成界面上的菜单。到目前为止,咱们已经基本了解了menuitem的基本使用方法,下面根据api文档,详细介绍属性、方法和事件。
初始化一个Menuitem对象,其中option是一个对象,包含label, icon, tooltip, type, click, checked, enabled 和 submenu这些字段。这些字段都具备本身的属性,下面分别叙述。
获取一个menuitem的类别信息,到目前为止有三类menuitem,分别为separator, checkbox 和normal。
normal和separator类型的menuitem咱们都已经在上面的示例中见到,下面咱们添加一个checkbox类型的menuitem。
menu.append(new gui.MenuItem({ label: '请选择',type:'checkbox' }));
结果以下:
须要注意的是,type字段只能在初始化时设定,在运行时是不能修改menuitem的类型的。
获取或设置menuitem的label值,目前只支持纯文本。
菜单的图标,支持app内部的相对路径和系统路径。sepatater类型的menuitem不支持icon属性。只支持png格式的图片。
修改sumMenuItem,为它添加icon:
var subMenuItem = new gui.MenuItem({ label: '子菜单项', icon: '2655716405282662783.png' });
效果以下:
或者或者设置tooltip字段。所谓tooltip就是当鼠标滑动到菜单上显示的文本信息,相似于DOM元素中的title。
下面咱们继续修改subMenuItem,为其添加tooltip:
var subMenuItem = new gui.MenuItem({ label: '子菜单项', icon: '2655716405282662783.png',tooltip:'我是帅气的子菜单' });
很不幸,在个人windows 7机器上,tooltip没法显示。在ubuntu上,menubar是显示在全局菜单上,看起来有点怪异:
获取或设置menuitem是否被选中。
获取或者menuitem的enaled属性,enabled设置为false的menuitem不可被选中。
获取或者是子菜单。能够参考本文的示例。
获取或设置click事件的回调函数。
本文内容主要参考node-webkit的官方英文文档(https://github.com/rogerwang/node-webkit/wiki/Menu,https://github.com/rogerwang/node-webkit/wiki/MenuItem,https://github.com/rogerwang/node-webkit/wiki/Window-menu)。
下一篇文章,介绍Platform Services。
更多相关内容,欢迎访问玄魂的博客(更多node-webkit相关内容 http://www.xuanhun521.com/Blog/Tag/node-webkit)
ps:nw.js,electron交流群 313717550