# 菜單
`menu` 類可以用來創建原生菜單,它可用作應用菜單和
[context 菜單](https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XUL/PopupGuide/ContextMenus).
這個模塊是一個主進程的模塊,并且可以通過 `remote` 模塊給渲染進程調用.
每個菜單有一個或幾個菜單項 [menu items](menu-item.md),并且每個菜單項可以有子菜單.
下面這個例子是在網頁(渲染進程)中通過 [remote](remote.md) 模塊動態創建的菜單,并且右鍵顯示:
```html
<!-- index.html -->
<script>
const remote = require('electron').remote;
const Menu = remote.Menu;
const MenuItem = remote.MenuItem;
var menu = new Menu();
menu.append(new MenuItem({ label: 'MenuItem1', click: function() { console.log('item 1 clicked'); } }));
menu.append(new MenuItem({ type: 'separator' }));
menu.append(new MenuItem({ label: 'MenuItem2', type: 'checkbox', checked: true }));
window.addEventListener('contextmenu', function (e) {
e.preventDefault();
menu.popup(remote.getCurrentWindow());
}, false);
</script>
```
例子,在渲染進程中使用模板api創建應用菜單:
```javascript
var template = [
{
label: 'Edit',
submenu: [
{
label: 'Undo',
accelerator: 'CmdOrCtrl+Z',
role: 'undo'
},
{
label: 'Redo',
accelerator: 'Shift+CmdOrCtrl+Z',
role: 'redo'
},
{
type: 'separator'
},
{
label: 'Cut',
accelerator: 'CmdOrCtrl+X',
role: 'cut'
},
{
label: 'Copy',
accelerator: 'CmdOrCtrl+C',
role: 'copy'
},
{
label: 'Paste',
accelerator: 'CmdOrCtrl+V',
role: 'paste'
},
{
label: 'Select All',
accelerator: 'CmdOrCtrl+A',
role: 'selectall'
},
]
},
{
label: 'View',
submenu: [
{
label: 'Reload',
accelerator: 'CmdOrCtrl+R',
click: function(item, focusedWindow) {
if (focusedWindow)
focusedWindow.reload();
}
},
{
label: 'Toggle Full Screen',
accelerator: (function() {
if (process.platform == 'darwin')
return 'Ctrl+Command+F';
else
return 'F11';
})(),
click: function(item, focusedWindow) {
if (focusedWindow)
focusedWindow.setFullScreen(!focusedWindow.isFullScreen());
}
},
{
label: 'Toggle Developer Tools',
accelerator: (function() {
if (process.platform == 'darwin')
return 'Alt+Command+I';
else
return 'Ctrl+Shift+I';
})(),
click: function(item, focusedWindow) {
if (focusedWindow)
focusedWindow.toggleDevTools();
}
},
]
},
{
label: 'Window',
role: 'window',
submenu: [
{
label: 'Minimize',
accelerator: 'CmdOrCtrl+M',
role: 'minimize'
},
{
label: 'Close',
accelerator: 'CmdOrCtrl+W',
role: 'close'
},
]
},
{
label: 'Help',
role: 'help',
submenu: [
{
label: 'Learn More',
click: function() { require('electron').shell.openExternal('http://electron.atom.io') }
},
]
},
];
if (process.platform == 'darwin') {
var name = require('electron').remote.app.getName();
template.unshift({
label: name,
submenu: [
{
label: 'About ' + name,
role: 'about'
},
{
type: 'separator'
},
{
label: 'Services',
role: 'services',
submenu: []
},
{
type: 'separator'
},
{
label: 'Hide ' + name,
accelerator: 'Command+H',
role: 'hide'
},
{
label: 'Hide Others',
accelerator: 'Command+Alt+H',
role: 'hideothers'
},
{
label: 'Show All',
role: 'unhide'
},
{
type: 'separator'
},
{
label: 'Quit',
accelerator: 'Command+Q',
click: function() { app.quit(); }
},
]
});
// Window menu.
template[3].submenu.push(
{
type: 'separator'
},
{
label: 'Bring All to Front',
role: 'front'
}
);
}
var menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu);
```
## 類: Menu
### `new Menu()`
創建一個新的菜單.
## 方法
`菜單` 類有如下方法:
### `Menu.setApplicationMenu(menu)`
* `menu` Menu
在 OS X 上設置應用菜單 `menu` .
在windows 和 linux,是為每個窗口都在其頂部設置菜單 `menu`.
### `Menu.sendActionToFirstResponder(action)` _OS X_
* `action` String
發送 `action` 給應用的第一個響應器.這個用來模仿 Cocoa 菜單的默認行為,通常你只需要使用 `MenuItem` 的屬性 `role`.
查看更多 OS X 的原生 action [OS X Cocoa Event Handling Guide](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/EventOverview/EventArchitecture/EventArchitecture.html#//apple_ref/doc/uid/10000060i-CH3-SW7) .
### `Menu.buildFromTemplate(template)`
* `template` Array
一般來說,`template` 只是用來創建 [MenuItem](menu-item.md) 的數組 `參數` .
你也可以向 `template` 元素添加其它東西,并且他們會變成已經有的菜單項的屬性.
##實例方法
`menu` 對象有如下實例方法
### `menu.popup([browserWindow, x, y, positioningItem])`
* `browserWindow` BrowserWindow (可選) - 默認為 `null`.
* `x` Number (可選) - 默認為 -1.
* `y` Number (**必須** 如果x設置了) - 默認為 -1.
* `positioningItem` Number (可選) _OS X_ - 在指定坐標鼠標位置下面的菜單項的索引. 默認為
-1.
在 `browserWindow` 中彈出 context menu .你可以選擇性地提供指定的 `x, y` 來設置菜單應該放在哪里,否則它將默認地放在當前鼠標的位置.
### `menu.append(menuItem)`
* `menuItem` MenuItem
添加菜單項.
### `menu.insert(pos, menuItem)`
* `pos` Integer
* `menuItem` MenuItem
在制定位置添加菜單項.
### `menu.items()`
獲取一個菜單項數組.
## OS X Application 上的菜單的注意事項
相對于windows 和 linux, OS X 上的應用菜單是完全不同的style,這里是一些注意事項,來讓你的菜單項更原生化.
### 標準菜單
在 OS X 上,有很多系統定義的標準菜單,例如 `Services` and
`Windows` 菜單.為了讓你的應用更標準化,你可以為你的菜單的 `role` 設置值,然后 electron 將會識別他們并且讓你的菜單更標準:
* `window`
* `help`
* `services`
### 標準菜單項行為
OS X 為一些菜單項提供了標準的行為方法,例如 `About xxx`,
`Hide xxx`, and `Hide Others`. 為了讓你的菜單項的行為更標準化,你應該為菜單項設置 `role` 屬性.
### 主菜單名
在 OS X ,無論你設置的什么標簽,應用菜單的第一個菜單項的標簽始終未你的應用名字.想要改變它的話,你必須通過修改應用綁定的 `Info.plist` 文件來修改應用名字.更多信息參考[About Information
Property List Files][AboutInformationPropertyListFiles] .
## 為制定瀏覽器窗口設置菜單 (*Linux* *Windows*)
瀏覽器窗口的[`setMenu` 方法][setMenu] 能夠設置菜單為特定瀏覽器窗口的類型.
## 菜單項位置
當通過 `Menu.buildFromTemplate` 創建菜單的時候,你可以使用 `position` and `id` 來放置菜單項.
`MenuItem` 的屬性 `position` 格式為 `[placement]=[id]`,`placement` 取值為 `before`, `after`, 或 `endof` 和 `id`, `id` 是菜單已經存在的菜單項的唯一 ID:
* `before` - 在對應引用id菜單項之前插入. 如果引用的菜單項不存在,則將其插在菜單末尾.
* `after` - 在對應引用id菜單項之后插入. 如果引用的菜單項不存在,則將其插在菜單末尾.
* `endof` - 在邏輯上包含對應引用id菜單項的集合末尾插入. 如果引用的菜單項不存在, 則將使用給定的id創建一個新的集合,并且這個菜單項將插入.
當一個菜檔項插入成功了,所有的沒有插入的菜單項將一個接一個地在后面插入.所以如果你想在同一個位置插入一組菜單項,只需要為這組菜單項的第一個指定位置.
### 例子
模板:
```javascript
[
{label: '4', id: '4'},
{label: '5', id: '5'},
{label: '1', id: '1', position: 'before=4'},
{label: '2', id: '2'},
{label: '3', id: '3'}
]
```
菜單:
```
- 1
- 2
- 3
- 4
- 5
```
模板:
```javascript
[
{label: 'a', position: 'endof=letters'},
{label: '1', position: 'endof=numbers'},
{label: 'b', position: 'endof=letters'},
{label: '2', position: 'endof=numbers'},
{label: 'c', position: 'endof=letters'},
{label: '3', position: 'endof=numbers'}
]
```
菜單:
```
- ---
- a
- b
- c
- ---
- 1
- 2
- 3
```
[AboutInformationPropertyListFiles]: https://developer.apple.com/library/ios/documentation/general/Reference/InfoPlistKeyReference/Articles/AboutInformationPropertyListFiles.html
[setMenu]:
https://github.com/electron/electron/blob/master/docs/api/browser-window.md#winsetmenumenu-linux-windows
- 介紹
- 常見問題
- Electron 常見問題
- 向導
- 支持平臺
- 分發應用
- 提交應用到 Mac App Store
- 打包應用
- 使用 Node 原生模塊
- 主進程調試
- 使用 Selenium 和 WebDriver
- 使用開發人員工具擴展
- 使用 Pepper Flash 插件
- 使用 Widevine CDM 插件
- 教程
- 快速入門
- 桌面環境集成
- 在線/離線事件探測
- API文檔
- 簡介
- 進程對象
- 支持的 Chrome 命令行開關
- 環境變量
- 自定義的 DOM 元素
- File 對象
- &lt;webview&gt; 標簽
- window.open 函數
- 在主進程內可用的模塊
- app
- autoUpdater
- BrowserWindow
- contentTracing
- dialog
- globalShortcut
- ipcMain
- Menu
- MenuItem
- powerMonitor
- powerSaveBlocker
- protocol
- session
- webContents
- Tray
- 在渲染進程(網頁)內可用的模塊
- desktopCapturer
- ipcRenderer
- remote
- webFrame
- 在兩種進程中都可用的模塊
- clipboard
- crashReporter
- nativeImage
- screen
- shell
- 開發
- 代碼規范
- 源碼目錄結構
- 與 NW.js(原 node-webkit)在技術上的差異
- 構建系統概覽
- 構建步驟(OS X)
- 構建步驟(Windows)
- 構建步驟(Linux)
- 在調試中使用 Symbol Server