# node-webkit教程(6)Native UI API 之Menu(菜單)
> 作者:玄魂
> 來源:[node-webkit教程(6)Native UI API 之Menu(菜單)](http://www.cnblogs.com/xuanhun/p/3669216.html)
## 目錄
+ 6.1 Menu 概述
+ 6.2 menu api
+ 6.2.1 new Menu([option])
+ 6.2.2 Menu.items
+ 6.2.3 Menu.items.length
+ 6.2.4 Menu.items[i]
+ 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 小結
## 6.1 Menu 概述
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
}
}
```
運行結果如下:

## 6.2 menu api
### 6.2.1 new Menu([option])
構造函數,見上文。
### 6.2.2 Menu.items
獲取該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屬性。
### 6.2.3 Menu.items.length
menuitem的個數。參加上文demo。
### 6.2.4 Menu.items[i]
通過索引返回一個menuitem對象。
### 6.2.5 Menu.append(MenuItem item)
向當前菜單中添加一個menuitem對象,該對象在整個menuitem集合的尾部。
### 6.2.6 Menu.insert(MenuItem item, int i)
在menuitem集合的指定位置插入一個menuitem對象。
### 6.2.7 Menu.remove(MenuItem item)
從menuitem集合中移除一個menuitem對象。
### 6.2.8 Menu.removeAt(int i)
刪除menuitem集合中指定位置的menuitem對象。
### 6.2.9 Menu.item[x].click
設置menuitem集合中指定位置的menuitem對象的click事件,在menuDemo.html中添加如下代碼:
```
menu.items[0].click = function() {
var element = document.createElement('div');
element.appendChild(document.createTextNode(‘我被點擊了’));
document.body.appendChild(element);
};
```
結果如下:

點擊前

點擊后
### 6.2.10 Menu.popup(int x, int y)
在當前窗口的指定位置彈窗菜單。示例代碼見上文。
## 6.3 創建右鍵菜單
創建右鍵菜單,需要在頁面監聽`contextmenu` 事件,然后控制彈出菜單。修改之前的菜單彈出代碼:
```
document.body.addEventListener('contextmenu', function (ev) {
ev.preventDefault();
menu.popup(10, 10);
return false;
});
```
啟動時頁面如下:

單擊右鍵后,界面顯示菜單:

## 6.4 MenuItem
從上面的敘述中,我們已經知道,menu和menuitem的一起組合,才能最終組成界面上的菜單。到目前為止,我們已經基本了解了menuitem的基本使用方法,下面根據api文檔,詳細介紹屬性、方法和事件。
### 6.4.1 new MenuItem(option)
初始化一個Menuitem對象,其中option是一個對象,包含label, icon, tooltip, type, click, checked, enabled 和 submenu這些字段。這些字段都具有自己的屬性,下面分別敘述。
### 6.4.2 MenuItem.type
獲取一個menuitem的類別信息,到目前為止有三類menuitem,分別為separator, checkbox 和normal。
normal和separator類型的menuitem我們都已經在上面的示例中見到,下面我們添加一個checkbox類型的menuitem。
menu.append(new gui.MenuItem({ label: '請選擇',type:'checkbox' }));
結果如下:

需要注意的是,type字段只能在初始化時設定,在運行時是不能修改menuitem的類型的。
### 6.4.3 MenuItem.label
獲取或設置menuitem的label值,目前只支持純文本。
### 6.4.4 MenuItem.icon
菜單的圖標,支持app內部的相對路徑和系統路徑。sepatater類型的menuitem不支持icon屬性。只支持png格式的圖片。
修改sumMenuItem,為它添加icon:
var subMenuItem = new gui.MenuItem({ label: '子菜單項', icon: '2655716405282662783.png' });
效果如下:

### 6.4.5 MenuItem.tooltip
或者或者設置tooltip字段。所謂tooltip就是當鼠標滑動到菜單上顯示的文本信息,類似于DOM元素中的title。
下面我們繼續修改subMenuItem,為其添加tooltip:
```
var subMenuItem = new gui.MenuItem({
label: '子菜單項',
icon: '2655716405282662783.png',
tooltip:'我是帥氣的子菜單'
});
```
很不幸,在我的windows 7機器上,tooltip無法顯示。在ubuntu上,menubar是顯示在全局菜單上,看起來有點怪異:

### 6.4.6 MenuItem.checked
獲取或設置menuitem是否被選中。
### 6.4.7 MenuItem.enabled
獲取或者menuitem的enaled屬性,enabled設置為false的menuitem不可被選中。
### 6.4.8 MenuItem.submenu
獲取或者是子菜單。可以參考本文的示例。
### 6.4.9 MenuItem.click
獲取或設置click事件的回調函數。
## 6.6 小結
本文內容主要參考node-webkit的官方英文文檔([https://github.com/rogerwang/node-webkit/wiki/Menu](https://github.com/rogerwang/node-webkit/wiki/Menu),[https://github.com/rogerwang/node-webkit/wiki/MenuItem](https://github.com/rogerwang/node-webkit/wiki/MenuItem),[https://github.com/rogerwang/node-webkit/wiki/Window-menu](https://github.com/rogerwang/node-webkit/wiki/Window-menu))。
下一篇文章,介紹Platform Services。
- 中文 Wiki
- 支持列表
- 開始nw.js
- package.json
- 中文教程
- node-webkit學習(1)hello world
- node-webkit學習(2)基本結構和配置
- node-webkit學習(3)Native UI API概覽
- node-webkit學習(4)Native UI API 之window
- node-webkit教程(5)Native UI API 之Frameless window
- node-webkit教程(6)Native UI API 之Menu(菜單)
- node-webkit教程(7)Platform Service之APP
- node-webkit教程(8)Platform Service之Clipboard
- node-webkit教程(9)native api 之Tray(托盤)
- node-webkit教程(10)Platform Service之File dialogs
- node-webkit教程(11)Platform Service之shell
- node-webkit教程(12)全屏
- node-webkit教程(13)gpu支持信息查看
- node-webkit教程(14)禁用緩存
- node-webkit教程(15)當圖片加載失敗的時候
- node-webkit教程(16)調試typescript