Electron 阻止多次打开相同窗口

huangapple go评论70阅读模式
英文:

Electron prevent opening same window multiple times

问题

我正在开发一个 Electron 应用程序,其中包括几个独立的窗口。我正在使用按钮点击事件来打开新窗口并调用 window.open 方法。问题是,如果我多次点击按钮,每次都会打开相同的窗口。我希望防止打开同一个窗口超过一次。

这是点击事件的调用:

window.open('settings.html', '_blank');

这是settings.html页面的配置。

mainWindow.webContents.setWindowOpenHandler(({ url }) => {
  if (path.basename(url) === 'settings.html') {
    return {
      action: 'allow',
      overrideBrowserWindowOptions: {
        width: 400,
        height: 450,
        autoHideMenuBar: true,
        fullscreenable: false,
        webPreferences: {
          preload: path.join(__dirname, 'js', 'preload.js')
        }
      }
    }
  }
  return { action: 'deny' }
});

配置当前位于 createWindow() 函数中。

Electron 版本为 24.4

英文:

I am developing an Electron application which includes a few seperate windows. I am using a button click event to open new window and call window.open method. Problem is, if I click the button more than once, everytime same window opens. I want to prevent to open same window more than once.

This is the click event call.

window.open('settings.html', '_blank');

And this is configuration for settings.html page.

mainWindow.webContents.setWindowOpenHandler(({ url }) => {
  if (path.basename(url) === 'settings.html') {
    return {
      action: 'allow',
      overrideBrowserWindowOptions: {
        width: 400,
        height: 450,
        autoHideMenuBar: true,
        fullscreenable: false,
        webPreferences: {
          preload: path.join(__dirname, 'js', 'preload.js')
        }
      }
    }
  }
  return { action: 'deny' }
});

Configurations currently locating in createWindow() function.

Electron version is 24.4

答案1

得分: 0

你可以尝试使用 IPC 处理这个问题。在渲染器中调用 ipcRenderer.invoke("open-window", url),在主进程中使用 ipcMain.handle("open-window", (event, url) => {...})。在主进程中,你可以有一个 const browserWindows = [] 数组,用于存储你打开的浏览器窗口。在 ipcMain.handle() 中,你可以检查 browserWindows 数组,如果浏览器窗口已经打开,就不要再打开一个新的。如果没有打开,可以使用 new BrowserWindow(...) 打开一个新窗口,并将其添加到 browserWindows 数组中。确保渲染器的点击处理程序是异步的,这样你可以在 IPC 主进程处理打开请求时防止多次点击(但也许这不是必要的):

async onClick() {
  buttonDisabled = true;
  await ipcRenderer.invoke("open-window", url);
  buttonDisabled = false;
}

你可能还需要一些额外的逻辑,以从 browserWindows 数组中移除已关闭的浏览器窗口。

或者,也许你可以在 setWindowOpenHandler 中完成所有这些操作,而不是使用 IPC。你可以创建一个 windowUrls 数组,然后检查该数组,而不是检查 browserWindows 数组。更多信息可以在 Electron 文档 中找到。

英文:

you could try to handle that with ipc. call ipcRenderer.invoke("open-window", url) in renderer and ipcMain.handle("open-window", (event, url) => {...}) in main. In main you have const browserWindows = [] where you store the browserWindows you have opened so far. In ipcMain.handle() you check the browserWindows array if that browser window is already open, if yes: dont open another one. If no: open a new one with new BrowserWindow(...) and add it to the browserWindows array. Make the renderer click handler async, so that you can do something like that to prevent multiple clicks while ipcMain still need to handle your open request (but maybe that is not necessary):

async onClick() {
  buttonDisabled = true;
  await ipcRenderer.invoke("open-window", url);
  buttonDisabled = false;
}

https://www.electronjs.org/docs/latest/tutorial/ipc

you probably need some additional logic to remove browserWindows when they are closed from the browserWindows array.

Or maybe you can do all of that in the setWindowOpenHandler too instead of using ipc. You could create a windowUrls array for example and check that instead of a browserWindows array.

huangapple
  • 本文由 发表于 2023年5月29日 20:18:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/76357317.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定