You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

Electron中实现窗口Hover时隐藏标题栏的方案咨询

实现独立透明hover显示的Electron标题栏

嘿,这个效果我刚好折腾过,完全可以实现,根本不用开第二个窗口!核心是用Electron的自定义标题栏配置,结合CSS的hover状态和窗口透明属性来搞定,给你一步步拆解具体实现:

1. 主窗口基础配置

首先在主进程里创建窗口时,要去掉默认标题栏、开启窗口透明,同时配置必要的web偏好:

const { BrowserWindow, path } = require('electron');

const mainWindow = new BrowserWindow({
  width: 800,
  height: 600,
  frame: false, // 移除系统默认标题栏
  transparent: true, // 允许窗口背景透明
  webPreferences: {
    contextIsolation: true, // 遵循Electron安全规范
    preload: path.join(__dirname, 'preload.js') // 用preload桥接主进程和渲染进程
  }
});

mainWindow.loadFile('index.html');

2. 自定义标题栏的HTML结构

在渲染进程的index.html里,单独写标题栏的容器,和主内容区分开:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>自定义标题栏示例</title>
  <link rel="stylesheet" href="styles.css">
</head>
<body>
  <!-- 自定义标题栏 -->
  <div class="title-bar">
    <div class="title-bar-actions">
      <button id="min-btn">-</button>
      <button id="max-btn">□</button>
      <button id="close-btn">×</button>
    </div>
  </div>

  <!-- 应用主内容 -->
  <div class="main-content">
    这里是你的应用内容区域
  </div>

  <script src="renderer.js"></script>
</body>
</html>

3. CSS实现透明/hover切换效果

通过CSS固定标题栏位置,设置默认透明、hover时显示半透明背景,同时配置拖动区域:

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.title-bar {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 36px;
  background-color: rgba(20, 20, 20, 0); /* 默认完全透明 */
  -webkit-app-region: drag; /* 允许拖动整个标题栏区域 */
  transition: background-color 0.2s ease-in-out; /* 平滑过渡效果 */
  display: flex;
  justify-content: flex-end;
  align-items: center;
  padding-right: 12px;
}

/* 标题栏自身hover,或者主窗口body hover时,显示背景 */
.title-bar:hover,
body:hover .title-bar {
  background-color: rgba(20, 20, 20, 0.8); /* 半透明深色背景 */
}

.title-bar-actions button {
  -webkit-app-region: no-drag; /* 按钮区域禁止拖动,避免影响点击 */
  background: transparent;
  border: none;
  color: #fff;
  width: 28px;
  height: 28px;
  border-radius: 4px;
  cursor: pointer;
  margin-left: 6px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.title-bar-actions button:hover {
  background-color: rgba(255, 255, 255, 0.2);
}

.main-content {
  margin-top: 36px; /* 给标题栏预留空间,避免内容被遮挡 */
  padding: 20px;
  color: #fff;
}

4. 窗口控制按钮逻辑实现

用Electron的IPC通信,在preload.js里暴露API,连接主进程和渲染进程:

preload.js

const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('windowControls', {
  minimize: () => ipcRenderer.send('window-minimize'),
  maximize: () => ipcRenderer.send('window-maximize'),
  close: () => ipcRenderer.send('window-close')
});

主进程接收IPC事件

const { ipcMain } = require('electron');

// 最小化窗口
ipcMain.on('window-minimize', () => {
  mainWindow.minimize();
});

// 最大化/还原窗口
ipcMain.on('window-maximize', () => {
  mainWindow.isMaximized() ? mainWindow.unmaximize() : mainWindow.maximize();
});

// 关闭窗口
ipcMain.on('window-close', () => {
  mainWindow.close();
});

渲染进程绑定按钮事件

// 绑定窗口控制按钮点击事件
document.getElementById('min-btn').addEventListener('click', () => {
  window.windowControls.minimize();
});

document.getElementById('max-btn').addEventListener('click', () => {
  window.windowControls.maximize();
});

document.getElementById('close-btn').addEventListener('click', () => {
  window.windowControls.close();
});

5. 优化细节:窗口失焦时保持透明

如果想要窗口失去焦点时,标题栏自动变回透明,可以在主进程监听窗口焦点变化,通知渲染进程调整样式:

主进程添加监听

// 窗口失焦
mainWindow.on('blur', () => {
  mainWindow.webContents.send('window-blur');
});

// 窗口聚焦
mainWindow.on('focus', () => {
  mainWindow.webContents.send('window-focus');
});

渲染进程接收事件并调整样式

const { ipcRenderer } = require('electron');

ipcRenderer.on('window-blur', () => {
  const titleBar = document.querySelector('.title-bar');
  titleBar.style.backgroundColor = 'rgba(20, 20, 20, 0)';
});

ipcRenderer.on('window-focus', () => {
  const titleBar = document.querySelector('.title-bar');
  // 如果此时标题栏或body处于hover状态,恢复背景
  if (titleBar.matches(':hover') || document.body.matches(':hover')) {
    titleBar.style.backgroundColor = 'rgba(20, 20, 20, 0.8)';
  }
});

这样就能完美实现你想要的效果:标题栏独立在主窗口上方,默认完全透明,当hover标题栏或主窗口时,标题栏平滑显示半透明背景,完全不需要创建第二个窗口~

内容的提问来源于stack exchange,提问作者Matteo Piatti

火山引擎 最新活动