在完全加载窗口后显示它

31

当我使用electron命令创建基本应用程序并对其进行初始化时,它会显示一个空白窗口,过了一会儿才加载内容。

内容完全加载后,应该使用哪个事件和哪个对象来显示窗口?

window.webContent对象上的did-finish-load事件?或者是dom-ready?或者可能是其他什么?

app.js

var app = require('app'),
    Window = require('browser-window'),
    mainWindow = null;

require('crash-reporter').start();

app.on('ready', function() {
   mainWindow = new Window({ width: 600, height: 400, show: false });

   mainWindow.loadUrl('file://' + __dirname + '/index.html');
   mainWindow.show();

   //
   // mainWindow.webContent.on('did-finish-load', function() {
   //     something like that is a proper way?
   // });
   //
});

如果你的 <script src="require.js" data-main="app"></script> 位于页面底部,那么它将在页面加载时触发,因此你的 mainWindow 对象应该是正常的;require 中的工厂函数是脚本被调用后的回调函数。 - Data
我没有包含 require.js 标签,因为我使用具有完整 node.js 支持的 http://electron.io。 - Are
不了解 Electron,但我使用 socket.io;你可以发出自己的主题,然后服务器将使用 on() 事件来执行模拟回调的操作。socket.emit('ready', 'topic-string'); socket.on('topic-string', function() { //do stuff }); 这样,只有在客户端 / DOM 完成其任务后,Node 才会被调用。 - Data
4个回答

46

好的,我自己找到了答案。正确的事件是did-finish-load,应该像这样使用:

var Window = new BrowserWindow({ width: 600, height: 400, show: false });
Window.loadUrl('file://somefile.html');
Window.webContents.on('did-finish-load', function() {
    Window.show();
});

对于需要此答案的人- 在这里您可以查看官方的electron文档关于此主题的说明:

在加载页面时,如果窗口尚未显示,则当渲染器进程首次呈现页面时,将发出ready-to-show事件。在此事件之后显示窗口将没有视觉闪烁:

let win = new BrowserWindow({show: false})
win.once('ready-to-show', () => {
  win.show()
})

发现了一个打字错误,应该是Window.webContents而不是Window.webContexts。我尝试编辑帖子,但更改必须至少为6个字符长。 - Frank Hale
loadUrl 返回一个 Promise,当 did-finish-load 触发时解决。 - fionbio

9
这种方法可以使用,但最好的做法是使用API文档中提到的ready-to-show

在加载页面时,如果窗口尚未显示,则在渲染进程首次呈现页面时会发出ready-to-show事件。 在此事件之后显示窗口将没有视觉闪烁:

请注意:

通常在did-finish-load事件之后发出此事件,但对于具有许多远程资源的页面,可能会在did-finish-load事件之前发出。

最后,您应该更新背景颜色以尽可能接近窗口内容背景。这是一个例子:
const {BrowserWindow} = require('electron')
let win = new BrowserWindow({show: false, backgroundColor: '#420024'})
win.once('ready-to-show', () => {
  win.show()
})

您还可以添加快速 CSS 淡入淡出效果,使内容更加平滑。只需将以下代码添加到您的 CSS 中,并将 .ui.container 设置为您的根 DOM 元素的任何类。请注意,如果将其设置为 <body/>,则不起作用

  @keyframes fadein {
    from { opacity: 0; }
    to { opacity: 1; }
  }
  .ui.container {
    animation: fadein 0.420s;
  }

查看以下链接获取更多信息: https://electron.atom.io/docs/all/#using-ready-to-show-event https://www.christianengvall.se/electron-white-screen-app-startup/


我几个月前已经在我的回答中编辑过了,但是设置背景颜色的技巧肯定很有用! - Are
2
昨晚我还发现了一个新技巧,可以在内容的根元素上设置非常快速的CSS淡入效果。这与Mac在窗口上的淡入效果很搭配。在Windows中看起来也很不错。 - 1-14x0r

0
您可以尝试在不可见的iframe中加载内容,然后创建窗口并从iframe向窗口传输内容。

0
在Electron中运行React应用程序时,确保窗口在第一次渲染后从不闪烁白屏并已完整打开是相当棘手的。
根据Electron文档,ready-to-show可能在某些情况下比其他事件先触发,因此这是不够的。
事实证明,did-finish-load也可能在dom-ready之前触发,所以这也不够好。
由于之前有过几次失败的经验,我不想仅仅依赖于dom-ready最后一定会触发,所以我选择检查这三个事件是否都已触发。
以下是一个快速而不太优雅的解决方案,但它确实有效:
      let readyToShow = false;
      let loaded = false;
      let domReady = false;
      function check() {
        if (readyToShow && loaded && domReady) {
          win.show();
        }
      }
      win.once('ready-to-show', () => {
        readyToShow = true;
        check();
      });
      win.webContents.once('did-finish-load', () => {
        loaded = true;
        check();
      });
      win.webContents.once('dom-ready', () => {
        domReady = true;
        check();
      });

win是一个BrowserWindow实例,你已经在其上调用了loadURL等方法。这省略了额外的脚手架,以捕捉窗口被卡住而一个事件也没有触发的情况。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接