electron:无边框应用设计

# electron

使用electron创建窗口的时候,默认会使用window的边框以及工具栏,如果想要创建一个无边框的窗口,可以通过设置frame属性为false来实现。

1
2
3
4
5
6
7
8
// main.js
const { BrowserWindow } = require('electron')

let win = new BrowserWindow({
width: 800,
height: 600,
frame: false
})

这样就可以创建一个无边框的窗口了。但是随之又会带来两个问题:窗口无法拖拽以及无法最小化、最大化、关闭按钮消失(当然你也可以通过快捷键来使用这些功能)。

自定义窗口控制按钮

在 html内部,只能控制窗口的关闭,而最大化和最小化需要和主进程通信,然后再由主进程来控制窗口的最大化和最小化。

一般我们统一使用ipcMainipcRenderer将窗口的控制操作发送到主进程,然后由主进程来控制窗口的最大化、最小化和关闭(以便更好的控制窗口的行为)。

下面是一个简单的实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<!DOCTYPE html>
<html>
<head>
<title>无边框窗口</title>
<style>
#drag {
-webkit-app-region: drag;
}
</style>
</head>

<body>
<div id="drag">
<button id="min">-</button>
<button id="max">+</button>
<button id="close">x</button>
</div>
</body>

<script>
const { ipcRenderer } = require('electron')

document.getElementById('min').addEventListener('click', () => {
ipcRenderer.send('min')
})

document.getElementById('max').addEventListener('click', () => {
ipcRenderer.send('max')
})

document.getElementById('close').addEventListener('click', () => {
ipcRenderer.send('close')
})
</script>

</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// main.js
const { app, BrowserWindow, ipcMain } = require('electron')

let win

app.on('ready', () => {
win = new BrowserWindow({
width: 800,
height: 600,
frame: false
})

win.loadFile('index.html')

ipcMain.on('min', () => {
win.minimize()
})

ipcMain.on('max', () => {
if (win.isMaximized()) {
win.unmaximize()
} else {
win.maximize()
}
})

ipcMain.on('close', () => {
win.close()
})
})

窗口拖拽

想要使得窗口可以拖拽,只需要将元素的-webkit-app-region属性设置为drag即可。

1
2
3
#drag {
-webkit-app-region: drag;
}
1
<div id="drag"></div>

这样就可以使得div元素可以拖拽窗口了。

但是这样会使得div内部的元素无法点击,因为-webkit-app-region属性会使得元素变为一个拖拽区域。

想要解决这个问题办法也很简单,只需要将其内部不需要拖拽而是需要响应鼠标点击的元素的-webkit-app-region属性设置为no-drag即可。

完整实例

下面结合自定义窗口控制按钮和窗口拖拽来实现一个无边框窗口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<!DOCTYPE html>
<html>
<head>
<title>无边框窗口</title>
<style>
#drag {
-webkit-app-region: drag;
}

#control {
-webkit-app-region: no-drag;
}
</style>
</head>

<body>
<div id="drag">
<div id="control">
<button id="min">-</button>
<button id="max">+</button>
<button id="close">x</button>
</div>
</div>
</body>

<script>
const { ipcRenderer } = require('electron')

document.getElementById('min').addEventListener('click', () => {
ipcRenderer.send('min')
})

document.getElementById('max').addEventListener('click', () => {
ipcRenderer.send('max')
})

document.getElementById('close').addEventListener('click', () => {
ipcRenderer.send('close')
})

</script>

</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// main.js
const { app, BrowserWindow, ipcMain } = require('electron')

let win

app.on('ready', () => {
win = new BrowserWindow({
width: 800,
height: 600,
frame: false
})

win.loadFile('index.html')

ipcMain.on('min', () => {
win.minimize()
})

ipcMain.on('max', () => {
if (win.isMaximized()) {
win.unmaximize()
} else {
win.maximize()
}
})

ipcMain.on('close', () => {
win.close()
})
})

这样就可以实现一个无边框窗口了。


Reference