窗口自定义
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'
相同的布局结果。
窗口控件叠加层
窗口控件叠加层 API 是一种 Web 标准,它使 Web 应用能够在安装到桌面上时自定义其标题栏区域。Electron 通过 BrowserWindow
构造函数选项 titleBarOverlay
公开了此 API。
此选项仅在应用自定义 titlebarStyle
时有效。启用 titleBarOverlay
时,窗口控件将以其默认位置显示,并且 DOM 元素不能使用此区域下方的区域。
titleBarOverlay
选项接受两种不同的值格式。
在任何平台上指定 true
都会导致一个具有默认系统颜色的叠加区域
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({
titleBarStyle: 'hidden',
titleBarOverlay: true
})
在任何平台上,titleBarOverlay
也可以是一个对象。叠加层的高度可以通过 height
属性指定。在 Windows 和 Linux 上,可以使用 color
属性指定叠加层的颜色。在 Windows 和 Linux 上,可以使用 color
和 symbolColor
属性分别指定叠加层及其符号的颜色。支持 rgba()
、hsla()
和 #RRGGBBAA
颜色格式以应用透明度。
如果未指定颜色选项,则颜色将默认为其窗口控制按钮的系统颜色。类似地,如果未指定高度选项,则它将默认为默认高度
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()
滤镜仅应用于窗口的 Web 内容,因此无法将模糊效果应用于窗口下方的内容(即用户系统上打开的其他应用程序)。 - 当打开 DevTools 时,窗口将不透明。
- 在 Windows 上
- 禁用 DWM 时,透明窗口将无法工作。
- 无法使用 Windows 系统菜单或双击标题栏来最大化透明窗口。其背后的原因可以在 PR #28207 上看到。
- 在 macOS 上
- 透明窗口上不会显示原生窗口阴影。
创建点击穿透窗口
要创建点击穿透窗口,即使窗口忽略所有鼠标事件,您可以调用 win.setIgnoreMouseEvents(ignore) API
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
win.setIgnoreMouseEvents(true)
转发鼠标事件 macOS Windows
忽略鼠标消息会使 Web 内容忽略鼠标移动,这意味着不会发出鼠标移动事件。在 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;
}
提示:禁用上下文菜单
在某些平台上,可拖动区域将被视为非客户端框架,因此当您在其上单击鼠标右键时,系统菜单将弹出。为了使上下文菜单在所有平台上都正常运行,您不应在可拖动区域上使用自定义上下文菜单。