跳转到主内容

自定义窗口交互

自定义可拖拽区域

默认情况下,使用操作系统窗口外框提供的标题栏可以拖拽窗口。 移除默认标题栏的应用需要使用 app-region CSS 属性来定义可以用于拖拽窗口的指定区域。 设置 app-region: drag 会将一块矩形区域标记为可拖拽。

必须要指出的是,可拖拽区域会忽略所有的指针事件。 例如,与可拖拽区域重叠的按钮元素将不会在重叠区域内产生鼠标点击或者鼠标进入/退出事件。 设置 app-region: no-drag 会将一块矩形区域排除出可拖拽区域,从而重新启用指针事件。

要让整个窗口可拖拽,你可以向 body 的样式里添加 app-region: drag

styles.css
body {
app-region: drag;
}

请注意,如果您使整个窗口都可拖拽,则必须将其中的按钮标记为不可拖拽,否则用户将无法点击它们:

styles.css
button {
app-region: no-drag;
}

如果你只把自定义标题栏设置为可拖拽,你还需要设置标题栏里所有的按钮为不可拖拽。

提示:禁用文本选择

创建可拖拽区域时,拖拽行为可能与文本选择相冲突。 例如,当你拖拽标题栏时,你可能会意外选中它的文本内容。 为了避免这种情况,您需要在可拖拽区域中禁用文本选择,像这样:

.titlebar {
user-select: none;
app-region: drag;
}

提示:禁用上下文菜单

在某些平台上, 可拖拽区域将被视为non-client frame, 因此当您右键单击它时, 系统菜单将弹出。 要使上下文菜单在所有平台上都正确运行, 您永远也不要在可拖拽区域上使用自定义上下文菜单。

点击穿透窗口

要创建一个点击穿透窗口,也就是使窗口忽略所有鼠标事件,你可以调用 win.setIgnoreMouseEvents(ignore) API:

main.js
const { BrowserWindow } = require('electron')

const win = new BrowserWindow()
win.setIgnoreMouseEvents(true)

转发鼠标事件 macOS Windows

忽略鼠标消息会使网页内容无视鼠标移动,这意味着鼠标移动事件不会被发出。 在 Windows 和 macOS 上,可以使用一个可选参数将鼠标移动消息转发到网页,从而允许发出诸如 mouseleave 之类的事件:

main.js
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)
})
preload.js
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 元素上时网页会点击穿透,在它外面则会恢复正常。