Electron.js:从main.js传变量至HTML模板及列表闪显问题求助
解决Electron中SQLite数据传递到渲染页面后列表消失的问题
问题背景
我是JavaScript与Electron.js的初学者,正在开发一款待办事项管理器。尝试将从SQLite的todos.db中获取的标题列表填充到选择菜单中,但不清楚如何将数据库获取的变量传递至HTML渲染页面。点击对应按钮后,列表仅显示一秒便消失。
错误原因分析
- IPC消息发送时机错误:当前
main.js中先发送listNames消息,再加载delete-list.html。此时新页面尚未加载完成,渲染进程无法接收这条消息;即使偶然接收到,页面加载完成后DOM会重置,导致添加的选项消失。 - DOM操作时机过早:
index.js中的代码在<head>中加载,此时<select>元素尚未渲染完成,document.getElementById("list-select")可能返回null,无法成功添加选项。 - 未定义
deleteList函数:点击删除按钮时会触发未定义的函数,可能导致页面异常行为。
修复方案及代码修改
1. 调整主进程(main.js)的消息发送时机
先加载页面,等页面完全加载后再发送数据库数据:
const { app, BrowserWindow, ipcMain } = require('electron'); const path = require('path'); const sqlite3 = require('sqlite3').verbose(); const db = new sqlite3.Database('todos.db'); ipcMain.on("deleteList", (event, data) => { db.all('SELECT title FROM lists', [], function (error, rows) { if (error) { console.error(error); return; } const listNames = rows.map(row => row.title); // 先加载页面 mainWindow.loadFile(path.join(__dirname, 'delete-list.html')); // 监听页面加载完成事件,再发送数据 mainWindow.webContents.once('did-finish-load', () => { mainWindow.webContents.send("listNames", listNames); console.log("main js working"); }); }); });
2. 确保渲染进程(index.js)在DOM就绪后执行操作
将DOM操作包裹在DOMContentLoaded事件中:
const ipcRenderer = require('electron').ipcRenderer; document.addEventListener('DOMContentLoaded', () => { ipcRenderer.on("listNames", (event, listNames) => { const listSelect = document.getElementById("list-select"); console.log("index.js working") listNames.forEach(listName => { const option = document.createElement("option"); option.text = listName; option.value = listName; listSelect.appendChild(option); }); }); });
3. 完善delete-list.html的脚本位置与函数定义
将脚本移到<body>末尾,避免DOM未加载完成时执行;同时补充deleteList函数的基础实现:
<!DOCTYPE html> <html> <head> <title>Task Master</title> <link rel="stylesheet" type="text/css" href="index.css"> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Jost:wght@200&display=swap" rel="stylesheet"> </head> <body> <div class="main"> <div class="header"> <h2 id="heading">Task Master V1.0</h2> </div> <div class="operations"> <select id="list-select"> <option disabled selected>Select the list</option> </select> <button onclick="deleteList()" id="submit">Delete</button> <button id="home" onclick="window.location.href = 'index.html';">Back To Home</button> </div> </div> <!-- 将脚本移到body末尾 --> <script src="index.js" type="text/javascript"></script> <script> // 补充deleteList函数实现 function deleteList() { const selectedList = document.getElementById("list-select").value; if (!selectedList) return; // 这里可以添加IPC调用,通知主进程删除列表 ipcRenderer.send('deleteSelectedList', selectedList); } </script> </body> </html>
额外建议
- 在主进程中添加
deleteSelectedList的IPC监听,完成实际的数据库删除操作。 - 可以添加错误处理,比如当数据库查询失败时,向渲染进程发送错误提示。
内容的提问来源于stack exchange,提问作者Jayendra Kamesh
相关产品推荐
相关产品推荐

