窗口自定义
BrowserWindow
模块是 Electron 应用程序的基础,它提供了许多 API,可以更改浏览器窗口的外观和行为。在本教程中,我们将介绍 macOS、Windows 和 Linux 上窗口自定义的各种用例。
创建无边框窗口
无边框窗口是没有边框的窗口。不要与 Google Chrome 浏览器混淆,窗口边框是指窗口中不属于网页的部分(例如工具栏、控件)。
要创建无边框窗口,需要在 BrowserWindow
构造函数中将 frame
设置为 false
。
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ frame: false })
应用自定义标题栏样式 macOS Windows
标题栏样式允许你隐藏 BrowserWindow 的大部分边框,同时保持系统的原生窗口控件完好无损,并且可以使用 BrowserWindow
构造函数中的 titleBarStyle
选项进行配置。
应用 hidden
标题栏样式会导致隐藏标题栏和全尺寸内容窗口。
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ titleBarStyle: 'hidden' })
控制交通信号灯 macOS
在 macOS 上,应用 hidden
标题栏样式仍会显示左上角的标准窗口控件(“交通信号灯”)。
自定义交通信号灯的外观 macOS
customButtonsOnHover
标题栏样式会在你将鼠标悬停在上面之前隐藏交通信号灯。如果你想在 HTML 中创建自定义交通信号灯,但仍使用原生 UI 来控制窗口,这将非常有用。
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ titleBarStyle: 'customButtonsOnHover' })
自定义交通信号灯位置 macOS
要修改交通信号灯窗口控件的位置,有两个可用的配置选项。
应用 hiddenInset
标题栏样式会将交通信号灯的垂直内嵌偏移一个固定量。
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ titleBarStyle: 'hiddenInset' })
如果你需要对交通信号灯的位置进行更精细的控制,可以将一组坐标传递给 BrowserWindow
构造函数中的 trafficLightPosition
选项。
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
titleBarStyle: 'hidden',
trafficLightPosition: { x: 10, y: 10 }
})
以编程方式显示和隐藏交通信号灯 macOS
您还可以从主进程以编程方式显示和隐藏交通信号灯。win.setWindowButtonVisibility
根据其布尔参数的值强制显示或隐藏交通信号灯。
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
// hides the traffic lights
win.setWindowButtonVisibility(false)
注意:鉴于可用的 API 数量,实现此目的的方法有很多。例如,将
frame: false
与win.setWindowButtonVisibility(true)
相结合将产生与设置titleBarStyle: 'hidden'
相同的布局结果。
窗口控件叠加 macOS Windows
窗口控件叠加 API 是一项 Web 标准,当在桌面上安装时,它使 Web 应用程序能够自定义其标题栏区域。Electron 通过 BrowserWindow
构造函数选项 titleBarOverlay
公开了此 API。
此选项仅在 macOS 或 Windows 上应用自定义 titlebarStyle
时才起作用。启用 titleBarOverlay
时,窗口控件将显示在其默认位置,并且 DOM 元素无法使用此区域下方的区域。
titleBarOverlay
选项接受两种不同的值格式。
在任一平台上指定 true
将生成具有默认系统颜色的叠加区域
// on macOS or Windows
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
titleBarStyle: 'hidden',
titleBarOverlay: true
})
在任一平台上,titleBarOverlay
也可以是一个对象。在 macOS 和 Windows 上,可以使用 height
属性指定叠加的高度。在 Windows 上,可以使用 color
和 symbolColor
属性分别指定叠加及其符号的颜色。支持 rgba()
、hsla()
和 #RRGGBBAA
颜色格式以应用透明度。
如果未指定颜色选项,则颜色将默认为窗口控制按钮的系统颜色。同样,如果未指定高度选项,则它将默认为默认高度
// on Windows
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
titleBarStyle: 'hidden',
titleBarOverlay: {
color: '#2f3241',
symbolColor: '#74b1be',
height: 60
}
})
注意:一旦从主进程启用了标题栏覆盖,即可使用一组只读 JavaScript API 和 CSS 环境变量 从渲染器访问覆盖的颜色和维度值。
创建透明窗口
通过将 transparent
选项设置为 true
,可以创建一个完全透明的窗口。
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ transparent: true })
限制
- 无法点击透明区域。有关详细信息,请参阅 #1335。
- 透明窗口不可调整大小。在某些平台上,将
resizable
设置为true
可能会导致透明窗口停止工作。 - CSS
blur()
滤镜仅适用于窗口的网络内容,因此无法对窗口下方的内容(即用户系统上打开的其他应用程序)应用模糊效果。 - 打开 DevTools 时,窗口将不会透明。
- 在 Windows
- 禁用 DWM 时,透明窗口将不起作用。
- 无法使用 Windows 系统菜单或双击标题栏最大化透明窗口。其背后的原因可以在 PR #28207 中看到。
- 在 macOS
- 透明窗口上不会显示本机窗口阴影。
创建可点击窗口
要创建可点击窗口(即让窗口忽略所有鼠标事件),可以调用 win.setIgnoreMouseEvents(ignore) API
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
win.setIgnoreMouseEvents(true)
转发鼠标事件 macOS Windows
忽略鼠标消息会使网页内容对鼠标移动无感,这意味着不会发出鼠标移动事件。在 Windows 和 macOS 上,可以使用可选参数将鼠标移动消息转发到网页,从而允许发出诸如 mouseleave
之类的事件
const { BrowserWindow, ipcMain } = require('electron')
const path = require('node:path')
const win = new BrowserWindow({
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
ipcMain.on('set-ignore-mouse-events', (event, ignore, options) => {
const win = BrowserWindow.fromWebContents(event.sender)
win.setIgnoreMouseEvents(ignore, options)
})
window.addEventListener('DOMContentLoaded', () => {
const el = document.getElementById('clickThroughElement')
el.addEventListener('mouseenter', () => {
ipcRenderer.send('set-ignore-mouse-events', true, { forward: true })
})
el.addEventListener('mouseleave', () => {
ipcRenderer.send('set-ignore-mouse-events', false)
})
})
这使得网页在 #clickThroughElement
元素上方时可以单击,而在其外部时恢复正常。
设置自定义可拖动区域
默认情况下,无边框窗口不可拖动。应用程序需要在 CSS 中指定 -webkit-app-region: drag
以告知 Electron 哪些区域可拖动(如操作系统的标准标题栏),并且应用程序还可以使用 -webkit-app-region: no-drag
将不可拖动区域排除在可拖动区域之外。请注意,目前仅支持矩形形状。
要使整个窗口可拖动,可以将 -webkit-app-region: drag
添加为 body
的样式
body {
-webkit-app-region: drag;
}
请注意,如果你已将整个窗口设为可拖动,则还必须将按钮标记为不可拖动,否则用户将无法单击它们
button {
-webkit-app-region: no-drag;
}
如果你仅将自定义标题栏设置为可拖动,则还需要使标题栏中的所有按钮不可拖动。
提示:禁用文本选择
创建可拖动区域时,拖动行为可能会与文本选择冲突。例如,当你拖动标题栏时,你可能会意外选择其文本内容。为了防止这种情况,你需要在可拖动区域内禁用文本选择,如下所示
.titlebar {
-webkit-user-select: none;
-webkit-app-region: drag;
}
提示:禁用上下文菜单
在某些平台上,可拖动区域将被视为非客户端框架,因此当你右键单击它时,将弹出系统菜单。为了使上下文菜单在所有平台上都能正常运行,你绝不应在可拖动区域上使用自定义上下文菜单。