窗口间通信的问题
electron窗口通信比nwjs要麻烦的多
electron分主进程和渲染进程,渲染进程又分主窗口的渲染进程和子窗口的渲染进程
主窗口的渲染进程给子窗口的渲染进程发消息
1 2 3 4 5 6 7 8 9 10 11 |
subWin.webContents.on( 'dom-ready' , () => { subWin.webContents.send( 'message' , { title: self.$root.a[self.$root.aIndex].title, content: window.UE.instants.ueditorInstant0.getContent(), id: self.$root.a[self.$root.aIndex].id, winId: item.winId, siteId: item.id, url, type }); }); |
子窗口的渲染进程接收消息的代码
1 2 3 |
ipcRenderer.on( 'message' , (event, article) => { console.log(article); }) |
注意,应该dom-ready了之后再发,要不然你的子窗口进程有可能接收不到消息
子窗口的渲染进程给主窗口的渲染进程发消息比较麻烦
子窗口要先把消息发送给主进程,再由主进程中转给主窗口
1 2 3 4 5 |
const { ipcRenderer} = require( 'electron' ); ipcRenderer.send( 'articleRefreshMain' , { siteId: 'cnblogs' , url: url }); |
主进程接收消息后中转给主窗口渲染进程的代码
1 2 3 4 |
import { app, BrowserWindow,ipcMain } from 'electron' ipcMain.on( 'articleRefreshMain' , (event, message) => { mainWindow.webContents.send( 'contentRefreshRenderer' , message); }); |
主窗口渲染进程接收消息的代码
1 2 3 4 5 6 |
ipcRenderer.on( 'articleRefreshRenderer' , (e, message) => { self.$root.a[self.$root.aIndex][message.siteId] = { url: message.url } self.$root.needSave.a = true ; }); |
监听编辑器内图片删除的事件
通过黏贴或者拖拽进编辑器的图片,我把它复制到了文章的目录(用户本地目录)
如果用户在编辑文章的过程中,又删了这个图片,那么我应该在目录中也删除这个图片
这就需要监控文章编辑器的图片变化
我用的是H5的MutationObserver对象,理论上,用这个东西可以监控任何DOM的变化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
var editorDocument = document.getElementById( "ueditor_0" ).contentWindow.document; var observer = new MutationObserver(records => { self.$root.needSave.c = true ; records.forEach((item, index) => { if (item.removedNodes.length > 0 && item.removedNodes[0].tagName == "IMG" ) { var path = decodeURI(item.removedNodes[0].src.substr(7)); fs.unlink(path, err => { if (err) console.log(err); }); } }); }); observer.observe(editorDocument, { childList: true , subtree: true }); |
electron-vue获取app版本号的hack代码
本来electron获取app版本号很简单,只要如下即可(以下代码运行在main进程中)
1 2 |
import { app, BrowserWindow,ipcMain } from 'electron' var versionStr = app.getVersion(); |
getVersion: 如果应用程序的 package. json 文件中找不到版本号, 则返回当前包或者可执行文件的版本(就是electron的版本号)。
因为我用的electron-vue,他又两种模式,生产模式和开发模式
在生产模式下没任何问题
在开发模式下,它其实是起了一个webserver,让electron加载一个localhost的地址
这样做主要是为了使用vue的hotload的优势
但这样的话,electron就找不到 package. json 文件中的版本号了
怎么办呢?
我们在应用启动的时候,先在主进程中把版本号拿出来
1 2 3 4 5 6 7 |
if (process.env.NODE_ENV !== 'development' ) { global.__static = require( 'path' ).join(__dirname, '/static' ).replace(/\\/g, '\\\\' ) winURL = `file: //${__dirname}/index.html`; } else { app.getVersion = ()=> curVersion; winURL = `http: //localhost:9080`; } |
注意,我们通过app.getVersion = ()=> curVersion;把getVersion方法给hack了
把文章内容填入特殊的网站编辑器中
在处理文章提交到知乎的过程中
发现知乎用了一个特殊的编辑器,
(一个基于reactjs的编辑器,github上有开源的,忘记地址了)
怎么搞都搞不定,他甚至不支持设置HTML的内容
最后用了electron的操作剪切板的能力才搞定的
先把文章内容放到剪贴板,再focus知乎的编辑器,再执行黏贴事件
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
const { clipboard, ipcRenderer, remote } = require( 'electron' ); var win = remote.BrowserWindow.fromId( this .winId); win.focus(); setTimeout( function () { document.getElementsByClassName( "WriteIndex-titleInput" )[0].children[0].focus(); clipboard.writeText( this .title); win.webContents.paste(); setTimeout( function () { document.getElementsByClassName( "public-DraftEditor-content" )[0].click(); clipboard.writeHTML( this .doc.body.innerHTML); win.webContents.paste(); ipcRenderer.send( 'articleRefreshMain' , { siteId: 'zhihu' , url: window.location.href }); }.bind( this ), 800) }.bind( this ), 800) |
注意,如果要黏贴两个地方,最好间隔个几百毫秒
要不然网页还没反应过来,你就focus另一个地方了,会导致黏贴不成功。
开源说明
源码地址:https://github.com/xland/xiangxuema(界面截屏也在这里)
支持平台:win x64、mac x64、linux x64(打包编译脚本都在)
编译好的应用程序,我放到了阿里云的CDN里,下载速度超赞,大家可以下载来用用看
有什么问题,请不吝提交issue,有issue必回!