【问题标题】:Electron BrowserView is losing focus when I call win.loadFile(..)当我调用 win.loadFile(..) 时,Electron BrowserView 失去焦点
【发布时间】:2019-07-05 17:40:50
【问题描述】:

在我的 Electron 设置中,一旦应用加载,我就会显示一个基于 Web 的登录屏幕。它位于填充应用程序屏幕空间的 BrowserView 中。使用这种方法,我可以为登录页面禁用 nodeIntegration(因为它需要 jQuery,当 nodeIntegration 为 true 时不可用),同时为我的主应用程序启用它。

但我注意到从关闭登录视图到加载主应用程序之间存在延迟。例如可能需要 2 到 5 秒。

为了消除这种延迟,我开始使用“did-finish-load”事件预加载主应用程序。这意味着当出现登录屏幕时,我可以在“背景”中加载主应用程序。

但是,我遇到了 BrowserView 失去焦点的问题。这意味着用户需要手动单击登录输入。在我将调用添加到 win.loadFile('index.html') 后,这种情况开始发生。

到目前为止,我已经能够通过在主应用加载后将焦点传回 BrowserView 来缓解这种情况。但这并不完美,因为在此期间键盘输入会被忽略。

有没有更好的解决方法?我的代码如下。

const win = new BrowserWindow({
    width: 605, height: 550,
    minWidth: 605, minHeight: 550,
    useContentSize: true,
    maximizable: false,
    title: "My Window"
})

const view = new BrowserView({
    webPreferences: {
      // Enables support for jQuery and others by disabling nodeIntegration in this BrowserView
      nodeIntegration: false,
    }
})

win.setBrowserView(view)
view.setAutoResize({ width: true, height: true})
view.setBounds({ x: 0, y: 0, width: win.getContentBounds().width, height: win.getContentBounds().height })

view.webContents.loadURL('my login url')

view.webContents.once('did-finish-load', () => {
    // Load the main view in the background. This means it'll be available immediately when the login view closes.
    // But it also steals focus from the view so...
    win.loadFile('index.html')

    // Best fix so far but not perfect
    win.webContents.on('did-finish-load', () => view.webContents.focus())
})

view.webContents.on('login-complete-made-up-event', async (event) => {
    // Close the login page to show the main view
    view.destroy()
    // Set the focus onto the main view
    win.webContents.focus()
})

【问题讨论】:

  • “因为它需要 jQuery,当 nodeIntegration 为真时不可用”——我认为情况正好相反,至少在我的经验中。
  • 相信我是对的 - 阅读 electronjs.org/docs/… > 由于 Electron 的 Node.js 集成,在 DOM 中插入了一些额外的符号,如模块、导出、要求。这会导致一些库出现问题,因为它们想要插入具有相同名称的符号。

标签: electron focus


【解决方案1】:

修复相当简单。今天早上在 5 分钟内偶然发现了它。

view.webContents.once('did-finish-load', () => {
    // Load the main view in the background. This means it'll be available immediately when the login view closes.
    win.loadFile('index.html')

    // Place focus on the view for keyboard input. i.e. Otherwise the user needs to click.
    // Do this after loading index.html as the loadFile(..) steals focus
    view.webContents.focus()
})

【讨论】:

  • 嗨,谢恩!请问各位大神,如何在BrowserView和主进程之间交换消息?我还没有找到任何可行的例子。提前致谢
  • 谢谢谢恩。实际上我一直在尝试使用,就像在mainrenderer 之间、mainbrowserview 之间一样。但我没有看到这些消息。我想这一定是我错过了一些非常愚蠢的事情,所以我创建了这个 StackOverFlow 问题:stackoverflow.com/questions/71243812/…。请看一看。提前谢谢你
猜你喜欢
  • 2011-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多