Electron 默认是没有右键支持的,右键点击也不会有效果。为了能够提供一些右键的行为,需要在合适的时间点,手动构造菜单并显示出来。
这里对右键点击的判断,如果放在 render 层用 JavaScript 去监听 contextmenu
事件,虽然可以从 event.target
上拿到元素,但是要判断当前选择的位置、能否选择/黏贴、是否有拼写错误的单词等,都比较困难,很容易写出问题来。
Electron 暴露了 Chromium 的数据,在 WebContents 中增加了 context-menu
的事件。在这个事件的回调函数中,提供了很多的数据,能够帮助更好的了解当前的右键点击状态,从而更好地显示右键菜单项。
context-menu
的文档见这里。
这个功能提交的 Pull Request 见 #5379。
在 context-menu
的回调函数中,第二个参数提供了非常多有用的数据,比如:
- selectionText - 选中的文字
- misspelledWord - 当前的拼写错误单词(如果没有拼写错误,这里的返回是空字符串)
- editFlags - 包含了
canCut
, canCopy
, canPaste
, canSelectAll
等各式布尔值,用于表示当前右键的位置是否允许剪切/复制/黏贴/全选等操作。完整的列表可以参考文档。
一个例子:
const { remote, Menu } = require('electron');
const webContents = remote.getCurrentWebContents();
function buildMenuFromSuggestions(suggestions) {
if (suggestions.length === 0) return [];
return suggestions.map(function (suggestion) {
return {
label: suggestion,
click: function () {
webContents.replaceMisspelling(suggestion);
},
};
}).concat([
{ type: 'separator' },
]);
}
webContents.on('context-menu', (event, info) => {
const { canCut, canCopy, canPaste, canSelectAll } = info.editFlags;
const { misspelledWord } = info;
const suggestions = getCorrections(misspelledWord);
const menuConfig = buildMenuFromSuggestions(suggestions)
.concat([
{ label: 'Cut', role: 'cut', enabled: canCut },
{ label: 'Copy', role: 'copy', enabled: canCopy },
{ label: 'Paste', role: 'paste', enabled: canPaste },
{
label: 'Select All',
enabled: canSelectAll,
click: webContents.selectAll,
},
]);
const menu = remote.Menu.buildFromTemplate(menuConfig);
menu.popup(remote.getCurrentWindow());
});