likes
comments
collection
share

Electron 22版本的那些事Electron 22版本之后 new-window 事件被移除后的替换方法 WebV

作者站长头像
站长
· 阅读数 96

Electron 22版本之后 new-window 事件被移除后的替换方法

在老项目的重构过程中,我们发现之前使用的 Electron 16 版本中的 webview 组件可以通过直接监听 new-window 事件来获取要打开的弹窗 URL。然而,从 Electron 22 版本开始,这个事件已经被移除。

因此,在重构项目时,我们将 Electron 升级到了 22 版本,发现无法直接监听 webview 组件的 new-window 事件。经过查阅资料,我们了解到这个方法已被删除,因此只能寻找其他方式来实现该功能。

下面就是简述实现思路:

  1. WebView 尝试打开新窗口时,主进程拦截该请求。
  2. 主进程通过 IPC 发送消息到渲染进程。
  3. 渲染进程接收消息并派发自定义事件(new-window)。
  4. 渲染进程可以根据需要处理此事件,如显示模态框或更新界面等。

webview中的一个属性allowpopups记得设置(允许打开新弹窗)

实现代码如下:

main.js文件中

mainWindow.webContents.on('did-attach-webview', (event, wc) => {
  wc.setWindowOpenHandler((details) => {
    mainWindow.webContents.send('webview-new-window', wc.id, details);
    return { action: 'deny' };
  });
});
  • mainWindow.webContents.on('did-attach-webview', ...)

    • 这个事件在 WebView 被附加到主窗口时触发。
    • event 是事件对象,wc 是新创建的 WebView 的 WebContents 对象。
  • wc.setWindowOpenHandler((details) => {...})

    • 通过设置窗口打开处理程序,当 WebView 中尝试打开新窗口(例如,点击链接)时会触发这个处理函数。
    • details 包含有关要打开的新窗口的信息,例如 URL 和其他相关参数。
  • mainWindow.webContents.send('webview-new-window', wc.id, details)

    • 此行将一个名为 'webview-new-window' 的消息发送到主窗口的 WebContents。
    • 这个消息包含了当前 WebView 的 id 和打开新窗口的 details
  • return { action: 'deny' }

    • 最后,处理程序返回 { action: 'deny' },表示拒绝打开新窗口。这意味着不会创建新窗口,而是通过 IPC 将消息传递给渲染进程。

preload.js文件中

ipcRenderer.on('webview-new-window', (e, webContentsId, details) => {
  // console.log('webview-new-window', webContentsId, details);
  // 创建一个新的事件,并将 details 作为事件的 detail 属性
  const newEvent = new CustomEvent('new-window', { detail: details });
  document.getElementById('webview').dispatchEvent(newEvent);
});
  • const { ipcRenderer } = require('electron')

    • 导入 Electron 的 ipcRenderer 模块,用于在渲染进程与主进程之间进行异步通信。
  • ipcRenderer.on('webview-new-window', (e, webContentsId, details) => {...})

    • 监听 'webview-new-window' 消息。当主进程发送此消息时,会触发回调函数。
    • e 是事件对象,webContentsId 是 WebView 的 ID,details 是打开新窗口的详细信息。
  • console.log('webview-new-window', webContentsId, details)

    • 在控制台输出收到的消息信息,便于调试。
  • document.getElementById('webview').dispatchEvent(new Event('new-window'))

    • 创建并派发一个名为 'new-window' 的事件,通知与 WebView 相关的 DOM 元素发生了新窗口请求。

renderer.js文件中

document.getElementById('webview').addEventListener('new-window', () => {  
  console.log('got new-window event')  
})
  • document.getElementById('webview').addEventListener('new-window', () => {...})

    • 为 WebView 元素添加一个事件监听器,用于监听 'new-window' 事件。
    • 当 'new-window' 事件被派发时,执行回调函数。
  • console.log('got new-window event')

    • 在控制台输出一条信息,表明新窗口事件已被捕获。

目前还在学electron的路上越走越远,小白大家轻点喷 electron还有很多重大修改,有兴趣的jym可以去看一下 electron重大更改

转载自:https://juejin.cn/post/7423980772173512739
评论
请登录