electron 电子“准备显示”事件未按预期工作

hrirmatl  于 2023-03-16  发布在  Electron
关注(0)|答案(2)|浏览(247)

下面是我的应用程序Codey中的一段代码。

源代码/main.py

// Show window once it has finished initialising
docsWindow.once("ready-to-show", () => {
  if (darkMode) {
    docsWindow.webContents.send("dark-mode:toggle");
  }

  if (!isDarwin) {
    docsWindow.webContents.send("platform:not-darwin");
  }

  docsWindow.webContents.send("docs:jump", section);

  docsWindow.show();
});

源代码/文档/渲染器.js

window.api.darkMode.toggle.receive(toggleDarkMode);

当darkMode = true时,toggleDarkMode永远不会运行。
我的应用程序有两个不同的窗口-编辑器和文档窗口。对于这两个窗口,在“ready-to-show”事件中,“dark-mode:toggle”被发送到渲染器进程。然而,文档窗口在编辑器窗口工作时无法运行toggleDarkMode函数。

**注意:**应用程序必须使用“yarn package”打包,因为某些功能在开发环境中不起作用。

任何帮助都将不胜感激。
(Repo:https://github.com/Liamohara/Codey

nszi6y05

nszi6y051#

任何感兴趣的人。我找到解决问题的办法了。

源代码/main.py

// Show window once it has finished initialising
-    docsWindow.once("ready-to-show", () => {
+    docsWindow.webContents.once("did-finish-load", () => {
       if (darkMode) {
         docsWindow.webContents.send("dark-mode:toggle");
       }
    
       if (!isDarwin) {
         docsWindow.webContents.send("platform:not-darwin");
       }
    
       docsWindow.webContents.send("docs:jump", section);
    
       docsWindow.show();
     });

在文档窗口中,要呈现的HTML内容比编辑器窗口中要多。因此,加载DOM所需的时间更长,并且在加载完成之前会发出“ready-to-show”事件。使用“did-finish-load”事件可确保在DOM加载完成之前不会调用API函数。

0pizxfdo

0pizxfdo2#

问题出在docsWindow.webContents.send()函数上。这是一个盲目的和欺骗性的bug。

// Show window once it has finished initialising
      docsWindow.once("ready-to-show", () => {if (darkMode) {
    docsWindow.webContents.send("dark-mode:toggle");
  }

  if (!isDarwin) {
    docsWindow.webContents.send("platform:not-darwin");
  }

  docsWindow.webContents.send("docs:jump", section);

  docsWindow.show();
});

当窗口准备好显示时,它就被创建了,但是HTML and renderer process还没有加载,只是还没有注册处理程序。preload脚本得到了数据/消息,但是不知道要做什么。当侦听器注册时,主进程已经标记完成了,并继续其他代码行。
有时候,它之所以有效是因为呈现器进程在主进程发送消息和注册侦听器之前运行。
如果你在消息创建后就把它发送到窗口,那么它就没有时间加载页面和js来接收消息。
解决方案是将它 Package 在'did-finish-load'事件中,这样它就可以在发送消息之前等待页面准备就绪,就像您所做的那样。

/ Show window once it has finished initialising
-    docsWindow.once("ready-to-show", () => {
+    docsWindow.webContents.once("did-finish-load", () => {
       if (darkMode) {
         docsWindow.webContents.send("dark-mode:toggle");
       }
    
       if (!isDarwin) {
         docsWindow.webContents.send("platform:not-darwin");
       }
    
       docsWindow.webContents.send("docs:jump", section);
    
       docsWindow.show();
     });

第二种方法是最初将BrowserWindow.options.show设置为false,并且仅在发送信道/消息之后调用win.show()
一个二个一个一个
第三种方法是设置setTimeout函数,以便在确保renderer process已注册侦听器之后发送通道/消息

setTimeout(function() {
      win.webContents.send("channel", "test value")
     }, 1500);

另一种选择是使用电子提供的其他进程间通信方式(在下面的链接中有详细说明)ipcMainipcRenderer型号
https://www.electronjs.org/docs/latest/tutorial/ipc

相关问题