从这一期开始,我会陆续地总结桌面应用常用的一些功能案例,之后有类似需求举一反三即可。这节学习一下如何切换应用的主题。
如果您想要手动在亮/暗模式之间切换,您可以通过在nativeTheme
模块的themeSource
属性中设置所需的模式来做到这一点。此属性的值将传播到您的渲染进程。任何与prefers-color-scheme
相关的CSS规则都将相应地更新。
先上代码,之后再分析:
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>主题切换</title>
<link rel="stylesheet" type="text/css" href="./style.css">
</head>
<body>
<p>当前主题为:<strong id="theme-source">系统主题</strong></p>
<button id="toggle">切换为深色模式</button>
<button id="reset-to-system">切换系统主题</button>
<script src='./index.js'></script>
</body>
</html>
preload.js
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('darkMode', {
toggle: () => ipcRenderer.invoke('dark-mode:toggle'),
system: () => ipcRenderer.invoke('dark-mode:system')
})
index.js
document.getElementById('toggle').addEventListener('click', async () => {
const isDarkMode = await window.darkMode.toggle()
document.getElementById('theme-source').innerHTML = isDarkMode ? '深色主题' : '浅色主题'
document.getElementById('toggle').innerHTML= isDarkMode ? '切换为浅色主题' : '切换为深色主题'
})
document.getElementById('reset-to-system').addEventListener('click', async () => {
await window.darkMode.system()
document.getElementById('theme-source').innerHTML = '系统主题'
})
style.css
@media (prefers-color-scheme: dark) {
body { background: #333; color: white; }
}
@media (prefers-color-scheme: light) {
body { background: #ddd; color: black; }
}
main.js
const { app, BrowserWindow, ipcMain, nativeTheme } = require('electron')
const path = require('path')
function createWindow () {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
win.loadFile('index.html')
ipcMain.handle('dark-mode:toggle', () => {
if (nativeTheme.shouldUseDarkColors) {
nativeTheme.themeSource = 'light'
} else {
nativeTheme.themeSource = 'dark'
}
return nativeTheme.shouldUseDarkColors
})
ipcMain.handle('dark-mode:system', () => {
nativeTheme.themeSource = 'system'
})
}
app.whenReady().then(() => {
createWindow()
app.on('activate', () => {
if (BrowserWindow.getAllWindows().length === 0) {
createWindow()
}
})
})
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
运行效果如下(这个GIF有点慢,别介意):
CSS文件使用@media
媒体查询的prefers-color-scheme
来设置< body >
元素背景和文本颜色。然后就是用到了上一节教程用到的进程通信的知识。在main.js主进程里面通过nativeTheme.themeSource
来设置主题。nativeTheme.shouldUseDarkColors
返回一个布尔值,表示操作系统/Chromium当前是否启用了暗模式 , 如果你想修改这个值,你应该使用themeSource
。 nativeTheme.themeSource
可以有三个属性值:system
, light
和dark
。它用于覆盖和取代Chromium选择在内部主题使用的值。