Electron
简介
electron 由 chromium ,Node.js , Native API
GITHUB开发的开源框架,允许使用web技术开发桌面应用
开发环境搭建
electron 基于node环境,我们需要安装node, npm(可以通过npm安装包)
npm insatll electron --save-dev
通过 npx electron -v 进行检验
第一个程序
// electron 主进程
var electron = require('electron')
// 引用app
var app = electron.app
// 窗口引用
var BrowserWindow = electron.BrowserWindow
// 申明要打开的主窗口
var mainWindow = null
// 创建应用
app.on('ready', () => {
mainWindow = new BrowserWindow({
width: 800,
height: 800
})
// 加载静态页面
mainWindow.loadFile('./index.html')
mainWindow.on('closed', () => {
mainWindow = null
})
})
// 第二种做法
// var {
// app,
// BrowserWindow
// } = require('electron')
// function createWindow() {
// // win是窗口
// let win = new BrowserWindow({
// width: 800,
// height: 600,
// webPreferences: {
// nodeIntegration: true
// }
// })
// // 加载 index.html
// win.loadFile('index.html')
// }
// app.whenReady().then(createWindow)
简单示例
因为我们要使用node里面的fs 模块,所以在设置窗口时,增加全量使用node.js
const electron = require('electron')
/**
* 创建房间,点歌,付钱关闭房间
*/
const app = electron.app
const BrowserWindow = electron.BrowserWindow
let mainWindow = null
app.on('ready', () => {
mainWindow = new BrowserWindow({
width: 800,
height: 600,
// 这里要确定全量使用 node
webPreferences: {
nodeIntegration: true
}
})
mainWindow.loadFile('./index.html')
mainWindow.on('closed', () => {
mainWindow = null
})
})
remote模块的使用
当我们知道了Electron 有了主进程和渲染进程后,我们还要知道一件事,就是Electron 的API方法和模块也可以分为可以在主进程和渲染进程中使用,那如果我们想在渲染进程中使用主进程中的方法,可以使用 Electron Remote 解决在渲染和主进程的通讯。
const newWin = require('electron').remote.BrowserWindow
const btn1 = this.document.getElementById('btn1')
let win = null
window.onload = function () {
btn1.onclick = function () {
win = new newWin({
width: 600,
height: 600,
webPreferences: {
nodeIntegration: true
}
})
win.loadFile(path.join(__dirname, '/yellow.html'))
win.on('close', () => {
win = null
})
}
}
创建菜单和基本使用
在Electron 中编写菜单,首先需要建立一个模板,这个目标很类似我们JSON或者类的数组
可以在根目录建一个main 文件夹,意思是主进程中用到的代码都写这里,然后改目录下建一个menu.js 文件然后编写代码
const { Menu, BrowserWindow } = require('electron')
const path = require('path')
const template = [
{
label:'新建页面',
accelertor:'ctrl+n',
click:() => {
let win = new BrowserWindow({
width: 700,
height: 700,
webPreferences: {
nodeIntegration: true
}
})
win.loadFile(path.join(__dirname, '../yellow.html'))
win.on('closed', () => {
win = null
})
}
},
{
label:'帮助',
accelertor:'ctrl+h'
}
]
const m = Menu.buildFormTemplate(template)
Menu.setApplicationMenu(m)
然后再在 主进程 main.js 的ready生命周期中,直接导入我们的menu.js
require('./main/menu.js')
注意 Menu 属于主线程下的模块,所以只能在主线程中使用,这个需要注意!!
Electron 制作右键菜单
右键菜单的响应事件是写在渲染进程中的,也就是写在index.html中的,所以要是用,就得用到 remote 模块进行操作
先来看看右键的响应事件,我们打开render文件夹,添加个rightMenu.js文件,进行编写右键菜单监听事件
// 当我们向使用Menu 模块,又因为menu 模块是主进程中的模块,如果想要在渲染进程中使用,必须用remote, 因此
const { remote } = require('electron')
const rightTemplate = [
{
label:'复制',
accelerator:'ctrl+c'
},
{
label:'粘贴',
accelerator:'ctrl+v'
}
]
const m = remote.Menu.buildFromTemplate(rightTemplate)
window.addEventListener('contextmenu',(e)=>{
// 阻止浏览器默认的鼠标右键事件
e.preventDefault()
m.popup({window:remote.getCurrentWindow})
})
程序打开调试模式
由于我们更改了系统默认的头部菜单,因此原本的打开开发者模式的菜单也没有了,快捷键也失效了,因此我们可以在打开应用的时候,直接用代码打开开发者调试工具
mainWindow.webContents.openDevTools()
// 打开的动作当然是发生在 入口文件 ready 事件中
使用Shell在浏览器打开链接
如果不做任何处理,那么我们的a标签跳转将会在 electron 主进程窗口进行跳转,但是很多时候我们想要的并不是在electron 中跳转,而是通过弹开浏览器的方式进行跳转
我们需要在render 渲染文件夹下创建新的 js文件 对跳转做处理,监听跳转的事件。
const { shell } = require('electron')
// 获取点击的DOM元素
const btn = this.document.querySelector('#btn')
btn.onclick = function(e){
// 阻止默认事件
e.preventDefault()
const href = btn.getAttribute('href')
shell.openExternal(href)
}
Electron中嵌入网页和打开子窗口
在主进程中嵌入网页
类似 iframe 标签,需要注意的是BrowserView 是主进程中的类,所以只能在主进程中使用
首先在 主进程 main.js 中引入并使用BrowserView 就可以实现键入网页到我们的应用中了
// ready后 引入BrowserView
const BrowserView = electron.BrowserView
// new 出对象
const view = new BrowserView()
// 嵌入BrowserView ,设置可用
mainWindow.setBrowserView(view)
// 定义样式和位置
view.setBounds({
x: 0,
y: 200,
width: 1200,
height: 800
})
// view 载入的页面
view.webContents.loadURL('http://baidu.com')
用window.open打开子窗口
直接获取点击的btn DOM元素,监听点击事件,触发点击事件后 执行 window.open(‘跳转的URL’)即可
这区别于 BrowserWindow ,window.open() 的方式打开的窗口叫做子窗口, 而 BrowserWindow 方式跳转的则是新的页面
子窗口和父窗口通信
window.opener.postMessage( message, targetOrigin ) 是将信息发送给指定来源的父窗口,如果未指定来源则发送给* 即所有窗口
- message :传递单独消息, 是String 类型的值
- targetOrigin: 指定发送的窗口
以上是子窗口发的消息,父窗口通过 监听 message 事件接受信息
选择文件对话框
打开文件选择对话框使用 dialog.showOpenDialog()
方法来打开,他有两个参数,一个是设置基本属性,了另一个是回调函数,如果一部可以使用then来实现
-
title: String (可选) ,对话框的标题
-
defaultPath:String (可选) ,默认打开的路径
-
buttonLabel: String(可选),确认按钮的自定义标签,当为空时,将使用默认标签
-
filters: 文件选择过滤器,定义后可以对文件扩展名进行筛选
-
properties : 打开文件的属性,比如打开文件还是打开文件夹,甚至隐藏文件
-
整个dialog.showOpenDialog( ) 方法返回的是一个 Promise 对象,可以通过.then的方式拿到结果,动态给图片的DOM添加src ,即可展示我们选中的图片了
保存对话框
保存文件使用 dialog.showSaveDialog()
方法来操作
saveBtn.onclick = function(){
dialog.showSaveDialog({
title:'保存文件',
}).then(result=>{
console.log(result.filePath)
fs.writeFileSync(result.filePath,'技术胖一个前端爱好者')
}).catch(err=>{
console.log(err)
})
}
消息对话框的操作
dialog.showMessageBox()
他的属性还是比较多的,所以我们先来看一下他的相关属性
- type: String 类型(可选) 图标样式有 none,info,error,question 和 warning
- title:String类型,弹出框的标题
- message:String类型(必选message box的内容) 这个是必须要写 的
- buttons:数组类型
底部通知信息的制作
electron消息通知是通过H5的 window.Notification
来实现的
window.Notification
的参数
- title: 通知的标题,可以显示在通知栏上
- option: 消息通知的各种属性配置,以对象的形式进行配置。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="notifyBtn">通知消息</button>
</body>
<script>
var notifyBtn = document.getElementById('notifyBtn');
var option = {
title:'来订单了,出来接客了!',
body:'哈哈哈哈哈哈哈哈',
}
notifyBtn.onclick = function(){
new window.Notification(option.title,option)
}
</script>
</html>
注册全局快捷键
全局快捷键模块就是 globalShortcut
globalShortcut 是主进程中的模块,而且注册的都是全局的快捷键,所以尽量写在main,js中,打开main.js,然后先引入 globalShotcut.register
方法可以实现
var electron = require('electron')
var app = electron.app
var globalShortcut = electron.globalShortcut
var BrowserWindow = electron.BrowserWindow;
var mainWindow = null ;
app.on('ready',()=>{
mainWindow = new BrowserWindow({width:800,height:600})
globalShortcut.register('ctrl+e',()=>{
mainWindow.loadURL('https://jspang.com')
})
mainWindow.loadFile('test.html')
//监听关闭事件,把主窗口设置为null
mainWindow.on('closed',()=>{
mainWindow = null
})
})
这里需要注意的是,注册全局的快捷键必须在ready
事件之后,才能注册成功。
检测快捷键是否注册成功
可以使用globalShortcut.isRegistered()
方法,来检测快捷键是否注册成功,因为你可能同时打开很多软件,他们已经占用了一些快捷键的组合,所以并不是百分百成功的
let isRegister= globalShortcut.isRegistered('ctrl+e')?'Register Success':'Register fail'
console.log('------->'+isRegister)
这样就进行了检测,如果你在实际开发中,可能当有冲突时,软件是支持可以修改快捷键。
注销快捷键
因为我们注册的是全局的快捷键,所以当我们关闭软件或者窗口时,记得一定要注销我们的快捷键。防止关闭后打开其他软件和他们的快捷键冲突。
var electron = require('electron')
var app = electron.app
var globalShortcut = electron.globalShortcut
var BrowserWindow = electron.BrowserWindow;
var mainWindow = null ;
app.on('ready',()=>{
mainWindow = new BrowserWindow({width:800,height:600})
globalShortcut.register('ctrl+e',()=>{
mainWindow.loadURL('https://jspang.com')
})
let isRegister= globalShortcut.isRegistered('ctrl+e')?'Register Success':'Register fail'
console.log('------->'+isRegister)
mainWindow.loadFile('test.html')
//监听关闭事件,把主窗口设置为null
mainWindow.on('closed',()=>{
mainWindow = null
})
})
// 注销快捷键
app.on('will-quit',function(){
//注销全局快捷键的监听
globalShortcut.unregister('ctrl+e')
globalShortcut.unregisterAll()
})
剪贴板事件的使用
开发中我们经常会有给用户一个激活码,然后用户复制粘贴的情况,此时我们需要用到 clipboard
模块,也就是剪贴板模块
导入这个模块,使用 clipboard.writeText(code.innerHTML)
即可将内容复制到剪贴板中