添加keyCode事件逻辑后Electron sendPin方法调用报错
Electron 项目中 sendPin 函数调用失败,控制台抛出如下错误:
Uncaught TypeError: Cannot read properties of undefined (reading 'sendPin') at HTMLDocument.handlekeyUp (pin-pad:86:28) pin-pad:61 Uncaught TypeError: Cannot read properties of undefined (reading 'sendPin') at HTMLDivElement.<anonymous> (pin-pad:61:28)
添加键盘回车触发提交的代码前,点击页面上的Enter按钮提交PIN的功能完全正常,异常是在加入以下代码段后出现的:
if (13 === e.keyCode) { window.electronAPI.sendPin(Pin);
index.html(PIN输入页面)
<!DOCTYPE html> <html lang="en"> <head> <link rel="stylesheet" href="pinpad.css" /> <meta charset="UTF-8" /> <title>Electron Test - Pin Pad</title> <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" /> </head> <body> <div id="container"> <div id="wrapper"> <input type="password" id="display" disabled /> <div id="pin-pad"> <div data-number="1">1</div> <div data-number="2">2</div> <div data-number="3">3</div> <div data-number="4">4</div> <div data-number="5">5</div> <div data-number="6">6</div> <div data-number="7">7</div> <div data-number="8">8</div> <div data-number="9">9</div> <div>Enter</div> <div data-number="0">0</div> <div>Clear</div> </div> </div> </div> </body> <script> let display = document.getElementById("display"); let validKeys = [ "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "Enter", "Clear", ]; let pin = ""; document.getElementById("pin-pad").addEventListener("click", (event) => { if (!validKeys.includes(event.target.innerText)) { return; } if (event.target.innerText === "Enter") { window.electronAPI.sendPin(pin); return; } if (event.target.innerText === "Clear") { pin = display.value = ""; return; } pin = pin + event.target.innerText; display.value = "*".repeat(pin.length); }); ///tests const handlekeyUp = function (e) { e.stopPropagation(); const input = document.getElementById("display"); console.log(input, e.key, input.value); var reg = new RegExp("^[0-9]$"); const number = document.querySelector(`[data-number="${e.key}"]`); if (reg.test(e.key)) input.value += e.key; if (number) number.style.backgroundColor = "#fff"; if (13 === e.keyCode) { window.electronAPI.sendPin(Pin); } }; const handleKeyDown = (e) => { const number = document.querySelector(`[data-number="${e.key}"]`); if (!number) { return; } number.style.backgroundColor = "#eee"; }; document.addEventListener("keyup", handlekeyUp); document.addEventListener("keydown", handleKeyDown); </script> </html>
main.js(主进程代码)
const electronApp = require("electron").app; const electronBrowserWindow = require("electron").BrowserWindow; const electronIpcMain = require("electron").ipcMain; const nodePath = require("path"); // Prevent garbage collection let window; function createWindow() { const window = new electronBrowserWindow({ fullscreen: true, show: false, webPreferences: { nodeIntegration: false, contextIsolation: true, preload: nodePath.join(__dirname, "preload.js"), }, }); window.loadFile("pin-pad.html").then(() => { window.show(); }); return window; } electronApp.on("ready", () => { window = createWindow(); }); electronApp.on("window-all-closed", () => { if (process.platform !== "darwin") { electronApp.quit(); } }); electronApp.on("activate", () => { if (electronBrowserWindow.getAllWindows().length === 0) { createWindow(); } }); // --- electronIpcMain.on("pin", (event, pin) => { // Simple check of pin validity if (pin === "1234") { window.loadFile("sales.html"); } });
preload.js(预加载脚本)
const contextBridge = require("electron").contextBridge; const ipcRenderer = require("electron").ipcRenderer; contextBridge.exposeInMainWorld("electronAPI", { sendPin: (pin) => { ipcRenderer.send("pin", pin); }, });
代码里有3个明确问题,按影响优先级排序:
变量名大小写错误
全局存储输入PIN的变量是小写开头的pin,但键盘回车事件中传入的是大写开头的Pin。JavaScript大小写敏感,未声明的Pin变量会触发执行错误,打断上下文逻辑,连原有正常的点击提交逻辑也会受连带影响。
修复:将window.electronAPI.sendPin(Pin)改为window.electronAPI.sendPin(pin)。键盘输入逻辑不同步
handlekeyUp函数中,按下数字键时仅修改了输入框的显示值,没有同步更新全局pin变量,即使修复大小写问题,键盘输入的密码内容也不会被正确提交。
修复:将数字键处理逻辑修改为:if (reg.test(e.key)) { pin += e.key; input.value = "*".repeat(pin.length); }同时补充键盘按Clear/退格键的清空逻辑,和点击交互保持一致。
页面文件名不匹配
主进程createWindow中加载的页面是pin-pad.html,但提供的页面代码文件名为index.html,如果实际运行时两个文件内容不同步,比如pin-pad.html未同步最新代码,也会触发electronAPIundefined的错误。
修复:确认主进程加载的HTML文件和修改的代码文件是同一个,避免改了A文件但程序加载B文件的问题。
另外贴出的异常代码段末尾缺少闭合大括号},如果实际代码中漏写会直接触发JS语法错误,导致整个页面脚本执行失败,补全大括号即可。
内容的提问来源于stack exchange,提问作者erhan

