Electron中深度解读实现多tabs的几种方式

介绍

前一阵子写了一个Demo:electron-multi-tabs,也写了一篇文章:如何实现多tabs的模式。但其实自己对Electron的应用开发,了解也是很少。 最近看了一遍Electron 官网,发现,我Demo中使用的BrowserView 也是官网描述Deprecated的。 通过文章来了解下,几种实现多tabs的方式。

多tabs实现的方式

  • WebContentsView :(官方推介:WebContentsViews are not a part of the DOM---instead, they are created, controlled, positioned, and sized by your Main process. Using WebContentsView, you can combine and layer many pages together in the same BaseWindow.)
  • BrowserView (electron-multi-tabs使用的):(官方提示:The BrowserView class is deprecated, and replaced by the new WebContentsView class.)
  • Iframes :Iframe 在 Electron 中的行为与普通浏览器中类似。 在宿主页面的 Content Security Policy 允许范围内,一个 <iframe> 元素能在页面上显示外部网页。 要限制 <iframe> 标签中站点的功能数量,建议 使用 sandbox 属性 并且只允许您想要支持的功能。
  • WebViewWebViews are based on Chromium's WebViews and are not explicitly supported by Electron. 我们不能保证WebView API 在未来版本的 Electron 中仍然可用。 这就是为什么如果您想要使用<webview>标签,您需要在BrowserWindowwebPreferences 中设置 webviewTagtrue。(官方提示:我们不建议您使用 WebView,因为这个标签会发生剧烈的结构变化,可能会影响您应用程序的稳定性。 Consider switching to alternatives, like iframe and Electron's WebContentsView, or an architecture that avoids embedded content by design.)

多Tabs样例源码:electron-multi-tabs,效果图:

WebContentsView 官方样例

js 复制代码
    const { BaseWindow, WebContentsView } = require('electron')
    const win = new BaseWindow({ width: 800, height: 400 })

    const view1 = new WebContentsView()
    win.contentView.addChildView(view1)
    view1.webContents.loadURL('https://electronjs.org')
    view1.setBounds({ x: 0, y: 0, width: 400, height: 400 })

    const view2 = new WebContentsView()
    win.contentView.addChildView(view2)
    view2.webContents.loadURL('https://github.com/electron/electron')
    view2.setBounds({ x: 400, y: 0, width: 400, height: 400 })

简单理解下代码:创建了一个窗口,通过x坐标,把页面一分为二,左边一个页面,右边一个页面。BaseWindow的contentView对象可以添加无数个可视对象。

BrowserView 官方样例

js 复制代码
    // 在主进程中.
    const { app, BrowserView, BrowserWindow } = require('electron')

    app.whenReady().then(() => {
      const win = new BrowserWindow({ width: 800, height: 600 })

      const view = new BrowserView()
      win.setBrowserView(view)
      view.setBounds({ x: 0, y: 0, width: 300, height: 300 })
      view.webContents.loadURL('https://electronjs.org')
    })

上述的代码,实现的逻辑跟WebContentsView差不多。 原理:通过setBounds,设置width和height为0,则内容不可见;剩下的设置为window的width和height就可以了。

Iframes

这个官方都赖得给样例代码了,因为不推介啊。

js 复制代码
    const { BrowserWindow, webFrameMain } = require('electron')

    const win = new BrowserWindow({ width: 800, height: 1500 })
    win.loadFile('你的html')

    win.webContents.on(
      'did-frame-navigate',
      (event, url, httpResponseCode, httpStatusText, isMainFrame, frameProcessId, frameRoutingId) => {
        const frame = webFrameMain.fromId(frameProcessId, frameRoutingId)
        if (frame) {
          console.log(frame.url)
        }
      }
    )
  • 从官网上了解,frame.url在主进程中是只读的,所以,变更和设置iframe的url地址,需要通过preload.js这个桥梁文件进行。
  • 上述的设计思路:一个iframe,不停的切换url,显示不同的tab的相关内容,这样的好处是,内存永远是一个页面的大小。坏处是加载很慢,而且没有keepalive。如果要一个tab一个iframe,也是可行的,但是,为了内存考虑,还是需要做限制,如上限是10个tab。

总之,不推介。

WebView

警告

Electron的 webview 标签基于 Chromium webview,后者正在经历巨大的架构变化。 这将影响 webview 的稳定性,包括呈现、导航和事件路由。 We currently recommend to not use the webview tag and to consider alternatives, like iframe, a WebContentsView, or an architecture that avoids embedded content altogether.

启用

默认情况下,Electron >= 5禁用 webview 标签。 在构造 BrowserWindow 时,需要通过设置 webviewTag webPreferences选项来启用标签。 For more information see the BrowserWindow constructor docs.

html 复制代码
   <webview id="foo" src="https://www.github.com/" style="display:inline-flex; width:640px; height:480px"></webview>
js 复制代码
    <script>
      onload = () => {
        const webview = document.querySelector('webview')
        const indicator = document.querySelector('.indicator')

        const loadstart = () => {
          indicator.innerText = 'loading...'
        }

        const loadstop = () => {
          indicator.innerText = ''
        }

        webview.addEventListener('did-start-loading', loadstart)
        webview.addEventListener('did-stop-loading', loadstop)
      }
    </script>

使用 webview 标签将'guest'内容 (例如网页) 嵌入到您的 Electron 应用中。 Guest 内容包含在 webview 容器内。 应用中的嵌入页面可以控制外来内容的布局和重绘。

iframe不同, webview 独立于您的应用程序运行。 它拥有和你的页面不一样的权限并且所嵌入的内容和你应用之间的交互都将是异步的。 这将保证你的应用对于嵌入的内容的安全性。 ** 注意: **从宿主页上调用 webview 的方法大多数都需要对主进程进行同步调用。总之,不推介。

总结

我也是一个Electron开 发的新人,所以每走一步都会记录下来相关的一些心得。在这里跟大家一起共勉。

相关推荐
不总是9 小时前
Windows 系统 Node.js 免安装版(zip)安装与配置教程(2026 最新)
前端·windows·node.js
蓝乐16 小时前
Express 知识点总结
node.js·express
sTone8737517 小时前
Electron 进程架构模型
前端·electron
哈撒Ki17 小时前
快速入门 Electron
前端·面试·electron
kylinmin19 小时前
Node.js安装及环境配置超详细教程(以win11为例子)
node.js
AI科技星19 小时前
维度原本——基于超复数谱系的全域维度统一理论
c语言·前端·javascript·网络·electron
阿奇__19 小时前
基于 Node.js 与智谱 AI 的 RAG 工程实践
人工智能·node.js
hacker_LeeFei20 小时前
前端辨识:npx、npm 、pnpm的区别
前端·npm·node.js
cvcode_study21 小时前
Electron 制作自定义浏览器
前端·javascript·electron
天机️灵韵1 天前
Tauri 2.0与Electron的桌面应用技术选型比较
前端·electron·前端框架