Electron案例解析——切换主题颜色的案例

效果图

切换主题颜色

核心

Electron的 nativeTheme.themeSource属性,值是string。有三个参数:system, light 和 dark,用来覆盖、重写Chromium内部的相应的值

Election的api 描述
nativeTheme.themeSource 被用来覆盖、重写Chromium内部的相应的值 system, light 和 dark

文档

相关文档地址:https://www.electronjs.org/zh/docs/latest/api/native-theme#nativethemethemesource

目录结构

目录结构

index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8" />

<!-- 内容安全策略-->
    <meta
            http-equiv="Content-Security-Policy"
            content="default-src 'self'; script-src 'self'"
    />

    <meta
            http-equiv="X-Content-Security-Policy"
            content="default-src 'self'; script-src 'self'"
    />
    <!-- 样式表 -->
    <link rel="stylesheet" type="text/css" href="./styles.css">
    <!--窗口标题-->
    <title>切换应用主题颜色的案例</title>
</head>
<body>

<h1>切换应用主题颜色</h1>

<p>当前主题颜色: <strong id="theme-source">system</strong></p>

<button id="toggle-dark-mode">切换颜色模式</button>
<button id="reset-to-system">重置为系统色</button>
</body>
<!-- 加载渲染进程的 renderer.js 文件 -->
<script src="./renderer.js"></script>
</html>

main.js

//引入electron模块 app, BrowserWindow
const {app, BrowserWindow,ipcMain, nativeTheme} = require('electron/main') //引入electron模块, app
const path = require('node:path') //引入path模块
//创建窗口
const createWindow = () => {
  const win = new BrowserWindow({
    //设置窗口大小 宽度800 高度600
    width: 800,
    height: 600,
    webPreferences: {  //网页设置
      preload: path.join(__dirname, 'preload.js') //设置预加载脚本
    }
  })
//加载index.html
  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'  //切换到系统主题
})

//当Electron完成初始化并且准备创建窗口时调用createWindow()
app.whenReady().then(() => {
  //在应用准备就绪时调用函数
  createWindow()

  //如果没有窗口打开则打开一个窗口 (macOS) 这个是必须处理的兼容性问题
  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) {
      createWindow()
    }
  })
})

/**
 * 关闭所有窗口时退出应用 (Windows & Linux) 这个是必须处理的兼容性问题。
 * 这段代码是用于Electron框架中的事件监听,具体是监听window-all-closed事件。这个事件会在所有窗口都被关闭时触发。
 * 代码中的逻辑是,如果当前操作系统平台不是macOS('darwin'),则在所有窗口关闭后退出应用程序。
 * */
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') app.quit()
})

preload.js

/**
 * 预加载脚本在加载“index.html”之前运行在渲染器中。
 * 它可以访问Web API以及Electronic的渲染器处理模块和一些多边填充Node.Js功能。
 * https://www.electronjs.org/docs/latest/tutorial/sandbox
 */
// 引入electron模块,
const { contextBridge, ipcRenderer } = require('electron/renderer')
//contextBridge用于暴露接口到主进程
contextBridge.exposeInMainWorld('darkMode', {
    toggle: () => ipcRenderer.invoke('dark-mode:toggle'),  // 切换暗黑模式
    system: () => ipcRenderer.invoke('dark-mode:system')  // 切换系统默认模式
})

renderer.js

/**
 * 当点击切换按钮“toggle-dark-mode”时,切换系统主题并更新主题状态
 */
document.getElementById('toggle-dark-mode').addEventListener('click', async () => {
  const isDarkMode = await window.darkMode.toggle()  // 切换系统主题
  document.getElementById('theme-source').innerHTML = isDarkMode ? 'Dark' : 'Light' // 同时,更新主题状态
})
/**
 * 当点击切换按钮“reset-to-system”时,恢复系统默认主题并更新主题状态
 */
document.getElementById('reset-to-system').addEventListener('click', async () => {
  await window.darkMode.system()  // 设置为系统默认主题
  document.getElementById('theme-source').innerHTML = 'System' // 同时,更新主题状态
})

style.css

:root {
    color-scheme: light dark;
}

/*这里是替换的样式代码 start*/
@media (prefers-color-scheme: dark) {
    body { background: #333; color: white; }
}

@media (prefers-color-scheme: light) {
    body { background: #ddd; color: black; }
}
/*这里是替换的样式代码 end*/

看效果,命令行,运行

npm start

相关推荐

  1. 7、Copmose自定义颜色主题切换

    2024-07-20 09:32:01       41 阅读
  2. 前端主题切换多种方式

    2024-07-20 09:32:01       27 阅读
  3. springboot实现Aop(通知)切面编程案例

    2024-07-20 09:32:01       45 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-20 09:32:01       52 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-20 09:32:01       54 阅读
  3. 在Django里面运行非项目文件

    2024-07-20 09:32:01       45 阅读
  4. Python语言-面向对象

    2024-07-20 09:32:01       55 阅读

热门阅读

  1. esp8266模块(1)

    2024-07-20 09:32:01       18 阅读
  2. Vue随笔【::v-deep 解决 样式污染的bug】

    2024-07-20 09:32:01       18 阅读
  3. 一种全局数据变化而且是多个的通知实现

    2024-07-20 09:32:01       18 阅读
  4. 极狐GitLab如何配置使用独立数据库?

    2024-07-20 09:32:01       18 阅读
  5. python 66 个冷知识 0716

    2024-07-20 09:32:01       16 阅读
  6. 【数据库技术NoSQL】MongoDB和Cassandra的使用

    2024-07-20 09:32:01       16 阅读
  7. live555搭建实时播放rtsp服务器

    2024-07-20 09:32:01       19 阅读
  8. 服务器相关总结

    2024-07-20 09:32:01       16 阅读
  9. ES6 字符串的新增方法(二十)

    2024-07-20 09:32:01       14 阅读
  10. C语言初学者入门指南

    2024-07-20 09:32:01       13 阅读
  11. 如何看待中国信息协会2024年网络安全大赛

    2024-07-20 09:32:01       14 阅读
  12. Symfony框架概述

    2024-07-20 09:32:01       16 阅读
  13. go reflect的工程使用

    2024-07-20 09:32:01       17 阅读
  14. RKE部署k8s

    2024-07-20 09:32:01       19 阅读