03_Electron 主进程和渲染进程、点击(拖放)打开文件功能

Electron 主进程和渲染进程

  • [一、Electron 主进程和渲染进程](#一、Electron 主进程和渲染进程)
  • [二、Electron 主进程和渲染进程中使用 Nodejs 以及 Nodejs 第三方模块](#二、Electron 主进程和渲染进程中使用 Nodejs 以及 Nodejs 第三方模块)
    • [2.1、主进程中使用 Nodejs 模块](#2.1、主进程中使用 Nodejs 模块)
    • [2.2、渲染进程中 使用 Nodejs 模块](#2.2、渲染进程中 使用 Nodejs 模块)
    • [2.3、BrowserWindow 中通过 preload加载的js 文件可以直接使用nodejs 模块](#2.3、BrowserWindow 中通过 preload加载的js 文件可以直接使用nodejs 模块)
    • [2.4、渲染进程中直接使用 Nodejs 模块](#2.4、渲染进程中直接使用 Nodejs 模块)
    • [2.5 打开调试模式](#2.5 打开调试模式)
    • [2.6、点击按钮展示 文件内容](#2.6、点击按钮展示 文件内容)
  • [三、Electron 调用 h5 的拖放 api 结合 Nodejs fs 模块实现拖放打开文件功能](#三、Electron 调用 h5 的拖放 api 结合 Nodejs fs 模块实现拖放打开文件功能)

一、Electron 主进程和渲染进程

主进程和渲染器进程
package.json 中定义的入口被称为 主进程 。在主进程 中实例化 BrowserWindow 创建的 Web 页面被称为渲染进程,一个 Electron 应用只有一个主进程 ,但是可以有多个渲染进程,每个 Electron 中的 web 页面运行在它自己的渲染进程中

主进程使用 BrowserWindow 实例创建页面。每个 BrowserWindow 实例都在自己的渲染进程里运行页面。当一个 BrowserWindow 实例被销毁后,相应的渲染进程也会被终止。

进程(了解) : 进程(process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配的调度的基本单位,是操作系统结构的基础。
线程(了解) :在一个程序里的一个执行路线就叫做 线程(thread)。更准确的定义是:线程是 "一个进程内部的控制序列"。
线程和进程(了解):一个程序至少有一个进程,一个进程至少有一个线程。

我们 electron 启动以后就能够在 任务管理器中查看到主进程

创建另外一个 second.html 渲染进程,在 main.js 的 createWindow 中添加代码:

javascript 复制代码
const createWindow = ()=>{
	const mainWindow = new BrowserWindow({
		width:800,
		height:600
	})
  // __dirname 表示获取我们当前目录, path.join 会将两个参数合并成 d://electrondemo/index.html
	mainWindow.loadFile(path.join(__dirname, 'index.html'))
  const secondWindow = new BrowserWindow({
		width:800,
		height:600,
    parent: mainWindow
	})
  // __dirname 表示获取我们当前目录, path.join 会将两个参数合并成 d://electrondemo/index.html
	secondWindow.loadFile(path.join(__dirname, 'second.html'))
}

运行结果如下

二、Electron 主进程和渲染进程中使用 Nodejs 以及 Nodejs 第三方模块

2.1、主进程中使用 Nodejs 模块

Electron 主进程中无需任何配置就可以使用 nodejs 模块。

2.2、渲染进程中 使用 Nodejs 模块

1、BrowserWindow 中通过 preload 加载 js 文件可以直接使用 nodejs 模块

2、如果不使用 preload 加载的 js ,Electron5.x 之后没法在渲染进程中直接使用 nodejs,

2.3、BrowserWindow 中通过 preload加载的js 文件可以直接使用nodejs 模块

在页面运行其他脚本之前预先加载指定的脚本, 无论页面是否集成 Node,此脚本都可以访问 所有 Node API 脚本路径为文件的绝对路径

main.js 主进程 代码:

javascript 复制代码
const createWindow = ()=>{
	const mainWindow = new BrowserWindow({
		width:800,
		height:600,
    webPreferences: {
      preload: path.join(__dirname, 'render/preload.js')
    }
	})
  // __dirname 表示获取我们当前目录, path.join 会将两个参数合并成 d://electrondemo/index.html
	mainWindow.loadFile(path.join(__dirname, 'index.html'))
  fs.readFile("package.json",(err, data)=>{
    if(err) {
      console.log(err);
      return
    }else {
      console.log(data.toString())
    }
  })

}

2.4、渲染进程中直接使用 Nodejs 模块

如果不使用 preload 加载的 js ,Electron5.x 之后没法再渲染进程中直接使用 nodejs,如果我们想要再渲染进程中使用 nodejs 的话需要进行如下配置:
https://www.electronjs.org/docs/api/browser-window

javascript 复制代码
const mainWindow = new BrowserWindow({
	width:800,
	height:600,
    webPreferences: {
     nodeIntegration: true,
     contextIsolation: false
   }
})

主进程:

2.5 打开调试模式

不需要手动点击下面的选项就可以直接展示 调试窗口

javascript 复制代码
const createWindow = ()=>{
	const mainWindow = new BrowserWindow({
		width:800,
		height:600,
	    webPreferences: {
	      nodeIntegration: true,
	      contextIsolation: false
	    }
	})
  // __dirname 表示获取我们当前目录, path.join 会将两个参数合并成 d://electrondemo/index.html
	mainWindow.loadFile(path.join(__dirname, 'index.html'))
  // 打开调试模式
  mainWindow.webContents.openDevTools()
}

2.6、点击按钮展示 文件内容

目录结构:

preload.js 代码:

javascript 复制代码
const fs = require('fs')
window.onload=()=>{
  let openFileDom = document.getElementById("btnFile")
  let contentDom = document.getElementById("content")
  openFileDom.onclick = ()=>{
    fs.readFile("package.json",(err, data)=>{
      if(err) {
        console.log(err);
        return
      }else {
        console.log(data.toString())
        contentDom.innerHTML = data.toString()
      }
    })

  }
}

index.html 代码

html 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      #content {
        width: 300px;
        height: 300px;
        border: 1px solid red;
      }
    </style>
  </head>
  <body>
    <h1>这是一个 electron 的项目</h1>
    <button id="btnFile">打开</button>
    <div id="content"></div>
  </body>
  <script src="render/preload.js"></script>
</html>

三、Electron 调用 h5 的拖放 api 结合 Nodejs fs 模块实现拖放打开文件功能

1、H5 的拖放 api

https://www.w3cschool.cn/jsref/event-ondragover.html

ondragover 事件在可拖动元素或选取的文本正在拖动到放置目标时触发。

默认情况下,数据/元素不能放置到其他元素中。 如果要实现改功能,我们需要防止元素的默认处理方法。我们可以通过调用 event.preventDefault() 方法来实现 ondragover 事件

注意: 为了让元素可拖动,需要使用 HTML5draggable 属性。

提示: 链接和图片默认是可拖动的,不需要 draggable 属性。

在拖放的过程中会触发以下事件:

在拖动目标上触发事件 (源元素):

ondragstart - 用户开始拖动元素时触发

ondrag - 元素正在拖动时触发

ondragend - 用户完成元素拖动后触发

释放目标时触发的事件:

ondragenter - 当被鼠标拖动的对象进入其容器范围内时触发此事件

ondragover - 当某被拖动的对象在另一对象容器范围内拖动时触发此事件

ondragleave - 当被鼠标拖动的对象离开其容器范围内时触发此事件

ondrop - 在一个拖动过程中,释放鼠标键时触发此事件

注意: 在拖动元素时,每隔 350 毫秒会触发 ondragover 事件。

2、实现效果

3、完整代码

目录结构:

main.js 中的代码:

javascript 复制代码
const {app, BrowserWindow} = require('electron')
const path = require('path')

const createWindow = ()=>{
	const mainWindow = new BrowserWindow({
		width:800,
		height:600,
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false
    }
	})
  // __dirname 表示获取我们当前目录, path.join 会将两个参数合并成 d://electrondemo/index.html
	mainWindow.loadFile(path.join(__dirname, 'index.html'))
  // 打开调试模式
  mainWindow.webContents.openDevTools()
}
// 监听 electron ready 事件创建窗口
app.on('ready', createWindow);
// 监听窗口关闭的事件,关闭的时候退出应用, macOs 需要排除
app.on('window-all-closed', ()=>{
	if(process.platform !=='darwin') {
		app.quit();
	}
})

// Macos 中点击 dock 中的应用图标的时候重新创建窗口
app.on('activate', ()=>{
  if(BrowserWindow.getAllWindows().length === 0) {
    createWindow()
  }
})

index.html 代码

html 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      #content {
        width: 100%;
        height: 400px;
        overflow-y: auto;
        background-color: orange;
      }
    </style>
  </head>
  <body>
    <h1>这是一个 electron 的项目</h1>
    <div id="content"></div>
  </body>
  <script src="render/preload.js"></script>
</html>

preload.js 代码

javascript 复制代码
/**
 * ondragenter - 当被鼠标拖动的对象进入其容器范围内时触发此事件
ondragover - 当某被拖动的对象在另一对象容器范围内拖动时触发此事件
ondragleave - 当被鼠标拖动的对象离开其容器范围内时触发此事件
ondrop - 在一个拖动过程中,释放鼠标键时触发此事件
 */
let fs = require("fs")
window.onload=()=>{
  let contentDom = document.getElementById("content")
  // 阻止默认行为
  contentDom.ondragenter = contentDom.ondragover= contentDom.ondragleave = function(){
    return false
  }
  contentDom.ondrop=(e)=>{
    let path = e.dataTransfer.files[0].path
    console.log(e,  e.dataTransfer.files[0].path)
    fs.readFile(path, (err, data)=>{
      if(err) {
        console.log(err)
        return false
      } 
      contentDom.innerHTML = data

    })
  }
}
相关推荐
玩电脑的辣条哥2 小时前
Python如何播放本地音乐并在web页面播放
开发语言·前端·python
ew452182 小时前
ElementUI表格表头自定义添加checkbox,点击选中样式不生效
前端·javascript·elementui
suibian52352 小时前
AI时代:前端开发的职业发展路径拓宽
前端·人工智能
画月的亮2 小时前
element-ui 使用过程中遇到的一些问题及解决方法
javascript·vue.js·ui
Moon.92 小时前
el-table的hasChildren不生效?子级没数据还显示箭头号?树形数据无法展开和收缩
前端·vue.js·html
m0_526119402 小时前
点击el-dialog弹框跳到其他页面浏览器的滚动条消失了多了 el-popup-parent--hidden
javascript·vue.js·elementui
垚垚 Securify 前沿站2 小时前
深入了解 AppScan 工具的使用:筑牢 Web 应用安全防线
运维·前端·网络·安全·web安全·系统安全
工业甲酰苯胺5 小时前
Vue3 基础概念与环境搭建
前端·javascript·vue.js
lyj1689975 小时前
el-tree选中数据重组成树
javascript·vue.js·elementui
mosquito_lover16 小时前
怎么把pyqt界面做的像web一样漂亮
前端·python·pyqt