菜單
創建原生應用菜單和上下文菜單。
進程:主進程
new Menu()
創建新菜單。
靜態方法
Menu
類有以下方法:
Menu.setApplicationMenu(menu)
menu
Menu | null
在macOS上將 menu
設置成應用內菜單
在windows和Linux上,menu
將會被設置成窗口頂部菜單
在Windows和Linux中,可以在菜單的頂層標簽的某個字母前添加&
以綁定快捷鍵。 例如,使用&File
后可以使用Alt-F
呼出File的子選項。 被綁定快捷鍵的字母將會以下划線標出。 &
並不會在運行時顯示
傳遞 null
值可以禁用默認菜單。 在 Windows 和 Linux 上,使用此方法移除窗口上的菜單欄可能會有額外的效果。
注釋:如果應用沒有設置菜單的話,系統會生成一個默認菜單。 默認生成的菜單中包含了一些初始選項,例如 文件
,編輯
, 視圖
,窗口
,幫助
。
EN
Menu.getApplicationMenu()
返回 Menu | null
- 如果有設置, 則返回應用程序菜單, 如果沒設置,則返回 null
。
注釋:返回的 Menu
實例不支持動態添加或刪除菜單項, 但仍然可以動態修改 實例屬性 。
EN
Menu.sendActionToFirstResponder(action)
macOS
action
String
將 action
發送到應用程序的第一個響應方。 這用於模擬默認的 macOS 菜單行為。 通常你可以使用MenuItem
的role
屬性
有關 macOS 的本地操作的詳細信息, 請參閱 macOS Cocoa Event Handling Guide 。
EN
Menu.buildFromTemplate(template)
template
(MenuItemConstructorOptions | MenuItem)[]
返回 Menu
一般來說, template
是一個options
類型的數組,用於構建MenuItem。 使用方法可參考前文。
You can also attach other fields to the element of the template
and they will become properties of the constructed menu items.
實例方法
menu
對象具有以下實例方法:
menu.popup([options\])
-
options
Object (可選)
window
BrowserWindow (可選) - 默認為選中窗口.x
Number (可選) - 默認為當前鼠標的位置。 如果指定了y
,則該選項必選。y
Number (可選) - 默認為當前鼠標的位置。 如果指定了x
,則該選項必選。positioningItem
Number (optional) macOS - The index of the menu item to be positioned under the mouse cursor at the specified coordinates. 默認值為 -1。callback
Function (optional) - 會在菜單關閉后被調用.
將此菜單作為 browserWindow 中的上下文菜單彈出。
menu.closePopup([browserWindow])
-
browserWindow
BrowserWindow (可選) - 默認為選中窗口.
關閉 browserWindow
中的上下文菜單。
menu.append(menuItem)
menuItem
菜單項
將 menuItem
追加到菜單。
menu.getMenuItemById(id)
id
String
Returns MenuItem | null
the item with the specified id
menu.insert(pos, menuItem)
pos
IntegermenuItem
菜單項
將 menuItem
插入菜單的 pos
位置。
實例事件
Objects created with new Menu
or returned by Menu.buildFromTemplate
emit the following events:
注意: 某些事件僅在特定的操作系統上可用, 這些方法會被標記出來。
事件: 'menu-will-show'
返回:
event
Event
調用menu.popup()
事件時觸發該事件。
事件: 'menu-will-close'
返回:
event
Event
手動關閉彈出,或使用 menu.closePopup()
方法關閉彈出時,觸發該事件。
實例屬性
menu
對象還具有以下屬性:
menu.items
包含菜單項的 MenuItem []
數組。
每個 菜單
由多個 MenuItem
組成, 每個 MenuItem
可以有子菜單。
菜單項
添加菜單項到應用程序菜單和上下文菜單中
進程:主進程
有關示例, 請參見 Menu
。
在
new MenuItem(可選)
-
選項
對象
-
click
功能(可選)-
click(menuItem, browserWindow, event)
單擊菜單項時將調用。
menuItem
菜單項browserWindow
BrowserWindow | 未定義-如果未打開任何窗口,則不會定義。event
KeyboardEvent
-
role
字符串(可選) -可以是undo
,redo
,cut
,copy
,paste
,pasteAndMatchStyle
,delete
,selectAll
,reload
,forceReload
,toggleDevTools
,resetZoom
,zoomIn
,zoomOut
,togglefullscreen
,window
,minimize
,close
,help
,about
,services
,hide
,hideOthers
,unhide
,quit
,startSpeaking
,stopSpeaking
,zoom
,front
,appMenu
,fileMenu
,editMenu
,viewMenu
,recentDocuments
,toggleTabBar
,selectNextTab
,selectPreviousTab
,mergeAllWindows
,clearRecentDocuments
,moveTabToNewWindow
或windowMenu
-定義菜單項的動作,當指定該click
屬性時將被忽略。見角色 -
type
String (可選)-可以是normal
、separator
、submenu
、checkbox
或radio
。 -
label
String (可選) -
sublabel
String (可選) -
toolTip
字符串(可選)macOS-懸停此菜單項的文本。 -
accelerator
Accelerator (可選) -
icon
(NativeImage | String) (可選) -
enabled
Boolean (可選) - 如果為 false,該菜單項將會置灰且不可點擊。 -
acceleratorWorksWhenHidden
布爾值(可選)macOS-默認為true
,當false
項目不可見時,將阻止加速器觸發該項目。 -
visible
Boolean (可選)-如果為 false, 該菜單項將完全隱藏。 -
checked
Boolean (可選)-只應為checkbox
或radio
類型菜單項指定。 -
registerAccelerator
布爾值(可選)Linux Windows-如果為false,則不會在系統中注冊加速器,但仍會顯示該加速器。默認值true。 -
submenu
(MenuItemConstructorOptions[] | Menu) (optional) - Should be specified forsubmenu
type menu items. Ifsubmenu
is specified, thetype: 'submenu'
can be omitted. 如果該值不屬於Menu
,它將被函數Menu.buildFromTemplate
自動轉換。 -
id
字符串(可選)-在單個菜單中唯一。如果已定義,則可以通過position屬性將其用作對此項目的引用。 -
before
String [](可選)-將此項目插入具有指定標簽的項目之前。如果所引用的項目不存在,則該項目將插入菜單的末尾。還意味着所討論的菜單項應與該菜單項位於同一“組”中。 -
after
String[] (optional) - Inserts this item after the item with the specified label. 如果引用值不存在,那么該菜單項會插在這個菜單的尾部。 -
beforeGroupContaining
String [](可選)-為單個上下文菜單提供一種方法,以聲明其包含組在具有指定標簽的項目的包含組之前的位置。 -
afterGroupContaining
String [](可選)-為單個上下文菜單提供一種方法,以聲明其包含組在具有指定標簽的項目的包含組之后的位置。
-
注意: acceleratorWorksWhenHidden
只在MacOS中生效,因為在Windows和Linux中快捷鍵不會隨着隱藏菜單項而失效。 該選項讓用戶可以選擇關閉,因為這是本地 macOS 開發中的可能。 此屬性只能在macOS High Sierra 10.13或以上中使用。
在
角色
可以通過角色來為menu添加預定義行為。
最好給任何一個菜單指定 role
去匹配一個標准角色, 而不是嘗試在 click
函數中手動實現該行為。 內置的 role
行為將提供最佳的原生體驗。
使用 role
時, label
和 accelerator
值是可選的, 並為每個平台,將默認為適當值。
每個菜單項必須有一個role
,label
或在分離器的情況下type
。
role
屬性可以具有以下值:
undo
about
-觸發本機“關於”面板(Window上的自定義消息框,不提供其自身的框)。redo
cut
copy
paste
pasteAndMatchStyle
selectAll
delete
minimize
- 最小化當前窗口。close
- 關閉當前窗口.quit
- 退出程序reload
- 重新加載當前窗口。forcereload
- 忽略緩存,重新加載當前窗口。toggledevtools
- 在當前窗口中隱藏/顯示開發者工具。togglefullscreen
- 將當前窗口切換至全屏模式。resetzoom
- 將主頁的縮放級別重置為初始大小.zoomin
- 主頁面放大 10%.zoomout
-主頁面縮小 10%.fileMenu
-整個默認的“文件”菜單(關閉/退出)editMenu
-默認的 "編輯" 菜單 (包括撤消、復制等)viewMenu
-整個默認的“查看”菜單(重新加載,切換開發者工具等)windowMenu
-整個默認的“窗口”菜單(最小化,縮放等)。
以下附加角色在macOS上可用:
appMenu
-整個默認的“應用”菜單(關於,服務等)hide
-映射到hide
操作.hideOthers
-映射到hideOtherApplications
操作.unhide
-映射到unhideAllApplications
操作.startSpeaking
-映射到startSpeaking
操作.stopSpeaking
-映射到stopSpeaking
操作.front
-映射到arrangeInFront
操作.zoom
-映射到performZoom
操作.toggleTabBar
-映射到toggleTabBar
操作.selectNextTab
- 映射到selectNextTab
操作.selectPreviousTab
- 映射到selectPreviousTab
操作.mergeAllWindows
- 映射到mergeAllWindows
操作.moveTabToNewWindow
- 映射到moveTabToNewWindow
操作.window
- 這個子菜單是"Window" 菜單.help
-這個子菜單是 "Help" 菜單.services
-子菜單是“服務”菜單。這僅適用於在應用程序菜單使用,是不一樣的MacOS應用程序上下文菜單中使用的“服務”子菜單,這是不是在電子實現。recentDocuments
-這個子菜單是 "Open Recent" 菜單.clearRecentDocuments
-映射到clearRecentDocuments
操作.
在 macOS 上指定 role
時, label
和 accelerator
是影響菜單項的唯一選項。 所有其它選項都將被忽略。 不過,仍然支持小寫的role
,如toggledevtools
。
諾塔Bene的:在enabled
和visibility
屬性不可用於在MacOS托盤頂級菜單項。
在
實例屬性
以下為 MenuItem
實例的可用屬性:
在
menuItem.id
String
指定了該選項唯一的id,此屬性可被動態更改。
在
menuItem.label
一個String
指示項目的可見標簽。
在
menuItem.click
當 MenuItem 接收到 click 事件時激發的Function
. It can be called with menuItem.click(event, focusedWindow, focusedWebContents)
.
event
KeyboardEventfocusedWindow
瀏覽器窗口focusedWebContents
網頁內容
在
menuItem.submenu
一個Menu
(可選)包含菜單項的子菜單(如果有)。
在
menuItem.type
String
表示菜單項的類型 Can be normal
, separator
, submenu
, checkbox
or radio
.
在
menuItem.role
String`(可選) 指出菜單項的角色 Can be `undo`, `redo`, `cut`, `copy`, `paste`, `pasteAndMatchStyle`, `delete`, `selectAll`, `reload`, `forceReload`, `toggleDevTools`, `resetZoom`, `zoomIn`, `zoomOut`, `togglefullscreen`, `window`, `minimize`, `close`, `help`, `about`, `services`, `hide`, `hideOthers`, `unhide`, `quit`, `startSpeaking`, `stopSpeaking`, `zoom`, `front`, `appMenu`, `fileMenu`, `editMenu`, `viewMenu`, `recentDocuments`, `toggleTabBar`, `selectNextTab`, `selectPreviousTab`, `mergeAllWindows`, `clearRecentDocuments`, `moveTabToNewWindow` or `windowMenu
在
menuItem.accelerator
一個Accelerator
(可選)指示項目的加速器(如果已設置)。
在
menuItem.icon
A NativeImage | String
(可選),指示項目的圖標(如果已設置)。
在
menuItem.sublabel
一個String
指示項目的子標簽。
在
menuItem.toolTip
蘋果系統
一個String
指示項目的懸停文本。
在
menuItem.enabled
一個 Boolean
類型的值, 指示是否啟用該項, 該屬性可以動態改變
在
menuItem.visible
一個 Boolean
類型的值, 指示該項是否可見, 該屬性可以動態改變。
在
menuItem.checked
一個 Boolean
類型的值, 指示是否選中該項, 該屬性可以動態改變。
checkbox
菜單項將在選中時切換 checked
的開關屬性。
單選菜單項
將返回單擊時checked
屬性, 並將關閉同一菜單中所有相鄰項的屬性。
你可以為其他行為添加click
函數。
在
menuItem.registerAccelerator
一個Boolean
指示是否加速器應與系統進行注冊,或只是顯示。
此屬性可以動態更改。
在
menuItem.commandId
一個Number
指示項目的順序唯一ID。
在
menuItem.menu
Menu
該項目所屬的A。
示例
Menu
僅在主進程( main process)中可用, 但您也可以在渲染進程(render process)中通過 remote
模塊使用它。
主進程
在主進程中創建程序菜單的簡單API模版示例:
const { app, Menu } = require('electron')
const isMac = process.platform === 'darwin'
const template = [
// { role: 'appMenu' }
...(isMac ? [{
label: app.name,
submenu: [
{ role: 'about' },
{ type: 'separator' },
{ role: 'services' },
{ type: 'separator' },
{ role: 'hide' },
{ role: 'hideothers' },
{ role: 'unhide' },
{ type: 'separator' },
{ role: 'quit' }
]
}] : []),
// { role: 'fileMenu' }
{
label: 'File',
submenu: [
isMac ? { role: 'close' } : { role: 'quit' }
]
},
// { role: 'editMenu' }
{
label: 'Edit',
submenu: [
{ role: 'undo' },
{ role: 'redo' },
{ type: 'separator' },
{ role: 'cut' },
{ role: 'copy' },
{ role: 'paste' },
...(isMac ? [
{ role: 'pasteAndMatchStyle' },
{ role: 'delete' },
{ role: 'selectAll' },
{ type: 'separator' },
{
label: 'Speech',
submenu: [
{ role: 'startSpeaking' },
{ role: 'stopSpeaking' }
]
}
] : [
{ role: 'delete' },
{ type: 'separator' },
{ role: 'selectAll' }
])
]
},
// { role: 'viewMenu' }
{
label: 'View',
submenu: [
{ role: 'reload' },
{ role: 'forceReload' },
{ role: 'toggleDevTools' },
{ type: 'separator' },
{ role: 'resetZoom' },
{ role: 'zoomIn' },
{ role: 'zoomOut' },
{ type: 'separator' },
{ role: 'togglefullscreen' }
]
},
// { role: 'windowMenu' }
{
label: 'Window',
submenu: [
{ role: 'minimize' },
{ role: 'zoom' },
...(isMac ? [
{ type: 'separator' },
{ role: 'front' },
{ type: 'separator' },
{ role: 'window' }
] : [
{ role: 'close' }
])
]
},
{
role: 'help',
submenu: [
{
label: 'Learn More',
click: async () => {
const { shell } = require('electron')
await shell.openExternal('https://electronjs.org')
}
}
]
}
]
const menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu)
渲染進程
下面是通過 remote
模塊在網頁(render process)中動態創建右擊菜單的示例:
<!-- index.html -->
<script>
const { remote } = require('electron')
const { Menu, MenuItem } = remote
const menu = new Menu()
menu.append(new MenuItem({ label: 'MenuItem1', click() { console.log('item 1 clicked') } }))
menu.append(new MenuItem({ type: 'separator' }))
menu.append(new MenuItem({ label: 'MenuItem2', type: 'checkbox', checked: true }))
window.addEventListener('contextmenu', (e) => {
e.preventDefault()
menu.popup({ window: remote.getCurrentWindow() })
}, false)
</script>
MacOS中應用菜單注意事項
macOS 相比於 Windows 和 Linux 有着完全不同的應用程序菜單。 以下是一些有關使應用菜單更像原生應用菜單的注意事項。
標准菜單
MacOS有一些系統預定義的菜單,像是Services
and Windows
。 讓你的菜單更像MacOS標准菜單,只需設置菜單role
值為如下示之一,Electron便會自動認出並設置成標准菜單,:
window
help
services
標准菜單項操作
macOS 已經為某些菜單項提供了標准操作, 如 about xxx
、Hide xxx
和 Hide Others
。 若要將菜單項的操作設置為標准操作, 應設置菜單項的 role
屬性。
主菜單的名稱
在 macOS 中應用程序菜單的第一個項目的標簽總是你的應用程序的名字, 無論你設置什么標簽。 如要更改它, 請修改應用程序包的 Info. plist
文件。 有關詳細信息, 請參閱 About Information Property List Files 。
設置特定瀏覽器窗口的菜單 ( Linux Windows )
瀏覽器窗口的 setMenu
方法 可以設置特定瀏覽器窗口的菜單。
菜單項位置
你可以使用 before
, after
, beforeGroupContaining
, afterGroupContaining
和 id
來控制由 Menu.buildFromTemplate
生成的菜單項的位置.
before
- 在指定的標簽之前插入菜單項。 如果引用值不存在,那么該菜單項會插在這個菜單的尾部。 這還意味着,菜單項應該被放置在與引用項相同的組中。after
- 在指定的標簽之后插入菜單項。 如果引用值不存在,那么該菜單項會插在這個菜單的尾部。 這還意味着,菜單項應該被放置在與引用項相同的組中。beforeGroupContaining
- Provides a means for a single context menu to declare the placement of their containing group before the containing group of the item with the specified label.afterGroupContaining
- Provides a means for a single context menu to declare the placement of their containing group after the containing group of the item with the specified label.
默認情況下,除非有位置相關的屬性,所有的菜單項會按照模板中的順序排放。
示例
模板:
[
{ id: '1', label: 'one' },
{ id: '2', label: 'two' },
{ id: '3', label: 'three' },
{ id: '4', label: 'four' }
]
菜單:
- 1
- 2
- 3
- 4
模板:
[
{ id: '1', label: 'one' },
{ type: 'separator' },
{ id: '3', label: 'three', beforeGroupContaining: ['1'] },
{ id: '4', label: 'four', afterGroupContaining: ['2'] },
{ type: 'separator' },
{ id: '2', label: 'two' }
]
菜單:
- 3
- 4
- ---
- 1
- ---
- 2
模板:
[
{ id: '1', label: 'one', after: ['3'] },
{ id: '2', label: 'two', before: ['1'] },
{ id: '3', label: 'three' }
]
菜單:
- ---
- 3
- 2
- 1
案例
在主進程中渲染菜單
主進程
//為了管理應用程序的生命周期事件以及創建和控制瀏覽器窗口,您從 electron 包導入了 app 和 BrowserWindow 模塊 。
const { app, BrowserWindow,Menu } = require('electron')
//在此之后,你定義了一個創建 新的瀏覽窗口的函數並將 nodeIntegration 設置為 true,將 index.html 文件加載到窗口中(第 12 行,稍后我們將討論該文件)
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
//是否注入nodeapi
nodeIntegration: true,
//渲染進程是否啟用remote模塊
enableRemoteModule: true
}
})
win.loadFile('index.html')
}
//你通過調用 createWindow方法,在 electron app 第一次被初始化時創建了一個新的窗口。
app.whenReady().then(createWindow)
//您添加了一個新的偵聽器,當應用程序不再有任何打開窗口時試圖退出。 由於操作系統的 窗口管理行為 ,此監聽器在 macOS 上是禁止操作的
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
//您添加一個新的偵聽器,只有當應用程序激活后沒有可見窗口時,才能創建新的瀏覽器窗口。 例如,在首次啟動應用程序后或重啟運行中的應用程序
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
//5s后
setTimeout(()=>{
//menu item
const template = [
{label: "第一個菜單項目"},
{label: "第二個菜單項目"},
{role: "undo"},
{type: 'separator'},
{label: "第三個菜單項目"},
{label: "第四個菜單項目"},
];
//使用 menu item 創建menu對象
const menu = Menu.buildFromTemplate(template);
//設置菜單
Menu.setApplicationMenu(menu);
//彈出菜單
menu.popup();
}, 5000)
渲染進程
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>菜單</title>
</head>
<body>
<h1>菜單</h1>
</body>
</html>
效果
渲染進程中使用菜單並注冊點擊事件使用MenuItem
渲染進程
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>菜單</title>
</head>
<body>
<h1>菜單</h1>
<button onclick="openMenu()">點擊彈出菜單</button>
</body>
<script>
const { Menu, MenuItem } = require('electron').remote
function openMenu() {
//menu item
const template = [
{label: "第一個菜單項目"},
{label: "第二個菜單項目"},
{role: "undo"},
{type: 'separator'},
{label: "第三個菜單項目"},
{label: "第四個菜單項目"},
{label: "點擊測試", click : () => {
console.log('點擊事件觸發.....');
}
},
];
//使用 menu item 創建menu對象
const menu = Menu.buildFromTemplate(template);
//設置成應用菜單
//Menu.setApplicationMenu(menu);
//使用MenuItem
let item = new MenuItem({label : '這是MenuItem'});
menu.append(item);
//彈出菜單
menu.popup();
}
</script>
</html>
渲染進程中創建帶子菜單的菜單
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>菜單</title>
</head>
<body>
<h1>菜單</h1>
<button onclick="openMenu()">點擊彈出菜單</button>
</body>
<script>
const { Menu, MenuItem } = require('electron').remote
function openMenu() {
//menu item
const template = [
{label: "第一個菜單項目"},
{label: "第二個菜單項目"},
{role: "undo"},
{type: 'separator'},
{label: "第三個菜單項目"},
{label: "第四個菜單項目"},
{label: "點擊測試", click : () => {
console.log('點擊事件觸發.....');
}
},
new MenuItem({label : '這是子菜單測試', submenu:[
{label: '子菜單1'},
{label: '子菜單2'},
{label: '子菜單3'}
]})
];
//使用 menu item 創建menu對象
const menu = Menu.buildFromTemplate(template);
//設置成應用菜單
//Menu.setApplicationMenu(menu);
//使用MenuItem
let item = new MenuItem({label : '這是MenuItem'});
menu.append(item);
//彈出菜單
menu.popup();
}
</script>
</html>