跳转至

自定义窗口交互

自定义可拖拽区域

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

需要注意的是,可拖拽区域会忽略所有指针事件。例如,与可拖拽区域重叠的按钮元素不会在该重叠区域内触发鼠标点击或鼠标进入/离开事件。设置 app-region: no-drag 会将一个矩形区域从可拖拽区域中排除,从而重新启用指针事件。

若要使整个窗口可拖拽,可以将 app-region: drag 添加到 body 的样式中:

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

另外请注意,如果你已使整个窗口可拖拽,还必须将按钮标记为不可拖拽,否则用户将无法点击它们:

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

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

提示:禁用文本选择

创建可拖拽区域时,拖拽行为可能会与文本选择发生冲突。例如,当你拖拽标题栏时,可能会意外选中其中的文本内容。为防止这种情况,你需要像下面这样禁用可拖拽区域内的文本选择:

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

[!TIP] 在开发时,将 ELECTRON_DEBUG_DRAGGABLE_REGIONS 环境变量设置为... 以在窗口上方绘制 Electron 正在使用的可拖拽区域,并记录它们变化的频率以及开销。它是一个实验性调试辅助工具,而不是正式 API,可能会在没有警告的情况下更改或移除。

提示:禁用上下文菜单

在某些平台上,可拖拽区域会被视为非客户端框架,因此当你右键点击它时,会弹出系统菜单。为了让上下文菜单在所有平台上都能正确工作,你不应该在可拖拽区域上使用自定义上下文菜单。

点击穿透窗口

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

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

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

转发鼠标事件 macOS Windows

忽略鼠标消息会使 Web 内容无法感知鼠标移动,也就是说不会触发鼠标移动事件。在 Windows 和 macOS 上,可以使用一个可选参数将鼠标移动消息转发到 Web 页面,从而允许触发诸如 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)
  })
})

这会使 Web 页面在位于 #clickThroughElement 元素上方时变为点击穿透,并在离开该元素后恢复正常。

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 el/electron