📜  ElectronJS 中的无框窗口

📅  最后修改于: 2021-11-07 08:27:15             🧑  作者: Mango

ElectronJS是一个开源框架,用于使用能够在 Windows、macOS 和 Linux 操作系统上运行的 HTML、CSS 和 JavaScript 等 Web 技术构建跨平台原生桌面应用程序。它将 Chromium 引擎和NodeJS 组合成一个单一的运行时。

在复杂的桌面应用程序中,可能会出现这样的情况,即开发人员可能不得不在不中断用户体验的情况下在并行框架中执行额外的后台进程和计算任务。这些在并行框架内运行的后台进程不应作为额外的 GUI 窗口对用户可见,但应在需要时相应地激活。我们可以在许多现代桌面应用程序(例如 Google Chrome 网络浏览器)中看到这种行为。此外,开发人员可能希望将用户限制为具有有限功能的特定框架,例如在显示许可协议或条款和条件窗口时。在此类窗口中,标题栏、导航栏、上下文菜单被禁用,用户不应能够关闭/跳过/最小化窗口框架。 Electron 为我们提供了一种方法,通过它我们可以打开一个没有工具栏、边框或任何其他图形组件的窗口,或者使用新BrowserWindow对象的选项中的属性使整个窗口透明。这种窗口在 Electron 中被称为无框窗口。本教程将演示如何在 Electron 中创建无框窗口的功能。

我们假设您熟悉上述链接中介绍的先决条件。为了让 Electron 正常工作,需要在系统中预装nodenpm。

  • 项目结构:

项目结构

示例:按照 ElectronJS 中的动态样式中给出的步骤设置基本的 Electron 应用程序。复制文章中提供的main.js文件和index.html文件的样板代码。此外,执行 package.json文件中提到的必要更改以启动电子应用程序。我们将继续使用相同的代码库构建我们的应用程序。设置 Electron 应用程序所需的基本步骤保持不变。
包.json:

{
  "name": "electron-frameless",
  "version": "1.0.0",
  "description": "Frameless Window in Electron",
  "main": "main.js",
  "scripts": {
    "start": "electron ."
  },
  "keywords": [
    "electron"
  ],
  "author": "Radhesh Khanna",
  "license": "ISC",
  "dependencies": {
    "electron": "^8.3.0"
  }
}

输出:

Electron 中的无框架窗口: BrowserWindow 实例是Main Process 的一部分。为了在Renderer Process 中导入和使用BrowserWindow ,我们将使用 Electron远程模块。无框窗户是没有镀铬的窗户。 Chrome 是除网页本身之外的窗口的任何可见方面(例如,工具栏、菜单栏、边框等)。我们可以通过指定BrowserWindow对象的属性定义BrowserWindow实例作为无框透明窗口。

  • index.html :在该文件中添加以下代码段。
html

  

Frameless Window in Electron

     

     


javascript
const electron = require('electron')
// Import BrowserWindow using Electron remote
const BrowserWindow = electron.remote.BrowserWindow;
// let win = BrowserWindow.getAllWindows()[0];
  
var frame = document.getElementById('frame');
frame.addEventListener('click', (event) => {
    const win = new BrowserWindow({
        width: 800,
        height: 600,
        // Creating a Frameless Window 
        frame: false,
        webPreferences: {
            nodeIntegration: true
        }
    });
    win.loadURL('https://www.google.com/');
});
  
var frameless = document.getElementById('frameless');
frameless.addEventListener('click', (event) => {
    const win = new BrowserWindow({
        width: 800,
        height: 600,
        frame: false,
        webPreferences: {
            nodeIntegration: true
        }
    });
    win.loadFile('src/index.html');
    win.show();
});


html

  

Frameless Window in Electron


javascript
const electron = require('electron')
// Import BrowserWindow using Electron remote
const BrowserWindow = electron.remote.BrowserWindow;
// let win = BrowserWindow.getAllWindows()[0];
  
var transparent = document.getElementById('transparent');
transparent.addEventListener('click', (event) => {
    const win = new BrowserWindow({
        width: 800,
        height: 600,
        frame: false,
        webPreferences: {
            nodeIntegration: true
        },
        transparent: true,
    });
    win.show();
});


  • index.js :“创建无框窗口”和“创建无框可拖动窗口”按钮尚无任何相关功能。要更改此设置,请在index.js文件中添加以下代码。

javascript

const electron = require('electron')
// Import BrowserWindow using Electron remote
const BrowserWindow = electron.remote.BrowserWindow;
// let win = BrowserWindow.getAllWindows()[0];
  
var frame = document.getElementById('frame');
frame.addEventListener('click', (event) => {
    const win = new BrowserWindow({
        width: 800,
        height: 600,
        // Creating a Frameless Window 
        frame: false,
        webPreferences: {
            nodeIntegration: true
        }
    });
    win.loadURL('https://www.google.com/');
});
  
var frameless = document.getElementById('frameless');
frameless.addEventListener('click', (event) => {
    const win = new BrowserWindow({
        width: 800,
        height: 600,
        frame: false,
        webPreferences: {
            nodeIntegration: true
        }
    });
    win.loadFile('src/index.html');
    win.show();
});

要创建电子,无框:假属性设置在BrowserWindow实例的选项。通过设置此属性,用户将只能看到网页本身,而无需任何额外的 chrome 或 GUI 组件。请参阅输出以获得更好的理解。默认情况下,无框窗口是不可拖动的。应用程序需要指定-webkit-app-region:drag CSS 属性来告诉 Electron 哪些区域是可拖动的。为了使整个窗口可拖动,此 CSS 属性设置为 HTML 中body标记的样式。应用程序还可以使用-webkit-app-region: no-drag CSS 属性来指示不可拖动区域。一旦我们定义了一个无框窗口,我们就可以根据我们的外观和感觉自定义它,并提供自定义标题栏和自定义窗口控件。
注意– 当-webkit-app-region:drag CSS 属性设置为body标签时,我们需要将-webkit-app-region: no-drag CSS 属性设置为窗口内的按钮或任何可点击组件。否则,我们将无法点击那些可点击的组件。

注意:有时在无框窗口中,拖动行为可能与文本选择冲突。例如,通过标题栏拖动窗口时,我们可能会不小心选中标题栏上的文本。当自定义标题栏的大小特别小时会发生这种情况。为了防止这种情况,我们需要使用-webkit-user-select: none; 禁用文本选择。 CSS 属性。

注意:Electron 的 v8.3.0开始,当前仅支持可拖动区域的矩形形状。此外,已知 -webkit-app-region:drag CSS 属性在 Chrome 开发工具打开时存在问题。
– 在某些环境中,窗口内的可拖动区域可被视为非客户端框架。这意味着每当我们右键单击可拖动区域时,系统上下文菜单可能会打开。为了使上下文菜单正确运行,我们不应在可拖动区域上使用自定义上下文菜单。
所有操作系统平台都支持BrowserWindow实例的frame: false属性。此外,在 macOS 中,我们有更多的属性来定义无边框窗口而不是frame属性。如果我们在 macOS 中使用 frame属性,它会禁用标题栏窗口控件(在 macOS 中也称为交通灯)。相反,我们可以使用BrowserWindow实例选项中的 titleBarStyle属性来隐藏标题栏并使内容扩展整个窗口大小,同时仍保留窗口控件。

  • titleBarStyle: ‘hidden’此属性隐藏标题栏,使内容扩展到窗口的完整大小,但仍会在无边框窗口的左上角显示窗口控件。
  • titleBarStyle: ‘hiddenInset’此属性隐藏标题栏,但提供了另一种外观,其中窗口控件从无边框窗口的边缘稍微插入。
  • titleBarStyle: ‘customButtonsOnHover’此属性使用微型按钮作为窗口控件,并在无边框窗口左上角附近悬停时显示自定义抽屉。此属性只能与frame: false属性一起使用。

此时,在启动 Electron 应用程序时,我们应该能够激活应用程序中的Frameless窗口和Frameless 可拖动窗口。在本教程中,为了演示目的,我们分别在无框窗口中加载了一个外部网站,在无框可拖动窗口中再次加载了 index.html 文件。
输出:

  • index.html :现在我们将看到如何在应用程序中使无框窗口完全透明,并了解 Electron 中透明窗口的一些特性和局限性。

html


  

Frameless Window in Electron

  • index.js :“创建无框透明窗口”按钮尚无任何相关功能。要更改此设置,请在index.js文件中添加以下代码。

javascript

const electron = require('electron')
// Import BrowserWindow using Electron remote
const BrowserWindow = electron.remote.BrowserWindow;
// let win = BrowserWindow.getAllWindows()[0];
  
var transparent = document.getElementById('transparent');
transparent.addEventListener('click', (event) => {
    const win = new BrowserWindow({
        width: 800,
        height: 600,
        frame: false,
        webPreferences: {
            nodeIntegration: true
        },
        transparent: true,
    });
    win.show();
});

说明:为了在 Electron 中创建透明窗口,在 BrowserWindow实例的选项中设置了 transparent:true 属性。这些透明窗口可用于加载外部脚本、执行后台进程和附加计算任务。但是,从 Electron 的 v8.3.0开始,存在与透明窗口相关的某些限制。下面列出了一些更重要的限制:

  • 我们无法点击透明窗口。
  • 透明窗口不可调整大小。在 BrowserWindow实例的选项中设置resizable: true属性会使透明窗口在某些操作系统环境中停止工作。
  • 我们不能将模糊过滤器应用于透明窗口下方的内容,因为它只能应用于网页本身,因此透明窗口下方的内容将清晰可见。如上所述,我们也无法点击透明窗口。这也在输出中得到了证明。

要在Renderer Process 中获取当前BrowserWindow实例,我们可以使用 BrowserWindow对象提供的一些静态方法。

  • BrowserWindow.getAllWindows():此方法返回活动/打开的 BrowserWindow 实例的数组。在这个应用程序中,我们只有一个活动的BrowserWindow实例,它可以直接从 Array 中引用,如代码所示。
  • BrowserWindow.getFocusedWindow():此方法返回在应用程序中聚焦的 BrowserWindow 实例。如果未找到当前 BrowserWindow 实例,则返回null 。在这个应用程序中,我们只有一个活动的BrowserWindow实例,可以使用代码中所示的这种方法直接引用它。

此时,在启动 Electron 应用程序时,我们应该能够激活应用程序中的透明窗口。
输出:

注意:在创建透明窗口时,当我们在options中指定transparent:true属性的同时还要使用BrowserWindow对象的win.loadFile(filepath)win.loadURL(url)实例方法,Instance方法取优先级和带有内容的相应窗口被加载到应用程序中。但是,在win.loadFile(filepath) Instance 方法的情况下,只有没有任何背景的文件内容被加载到应用程序中。这也可用于增强应用程序的 GUI。请参阅下面的输出以获得更好的理解。
输出: