導言
近來對electron有點感興趣,奈何干啃官方文檔實在難受,還是直接從demo入手會比較好。受到一兩個教程的啟發,然后自己瞎搗鼓一下。
說明
利用Electron.js構建一個有以下功能的桌面端應用:
- 實現簡單的獲取文本框輸入的內容并保存為文件
- 能夠通過拖拽文件來讀取其中的信息
應用界面
因為只是demo ,為了方面,就只是加基礎樣式了,將就著看。
快速開始:
準備工作
以官方Electron的electron-quick-start作為腳手架,
# Clone this repository
git clone https://github.com/electron/electron-quick-start
# Go into the repository
cd electron-quick-start
# Install dependencies
npm install
# Run the app
npm start
這里試過坑。
在自己的電腦上這npm install
安裝依賴死活不成功,后來發現是Node.js還是Npm的版本有點老,就重裝過。因為國外的鏡像太慢,我換成cnpm之后。
你以為可以了,我也以為的時候,然后又出現了一個坑!
如果你的項目所在的硬盤格式是FAT32的話!就會又特么的報錯,無法安裝依賴。所以把項目轉移到NTFS格式的盤上吧。
好了,現在項目核心文件如下:
electron-quick-start/
├── package.json
├── renderer.js
├── main.js
└── index.html
//至于其他的文件如README.md , LICENSE.md , .gitignore 等等就不用管了,那不是重點
下面開始進行主要工作
目前這個demo只需修改下面兩個文件:
Index.html :
|——它是我們應用的前端
renderer.js
|—— 在其中添加前端功能的代碼,它可以讓你在此使用Node.js的API,超級強大
修改index.html
:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Write & Open File</title>
<!--
Electron 中引入jQuery的正確方式:
記得要安裝依賴
' npm install jquery --save '
-->
<script>window.$ = window.jQuery = require('jquery');</script>
</head>
<style>
body{
margin:0;
}
/* 輸入區域的樣式 */
#textarea_t {
width: 90%;
background: #eee;
margin: 2em;
padding: 1em;
outline: none;
}
/* 按鈕樣式 */
#btn_write{
width: 200px;
height: 35px;
background: #fff;
outline: none;
border: 1px solid #d2d2d2;
border-radius: 5px;
text-align: center;
display: block;
margin: 0 auto;
cursor: pointer;
transition: .3s all ease-in-out;
}
#btn_write:hover{
box-shadow: 1px 1px 20px rgba(117, 117, 117, 0.29);
}
/* 拖拽的區域樣式 */
.holder{
min-height: 200px;
background: #eee;
margin:2em;
padding:1em;
border:0px dotted #eee;
border-radius: 10px;
transition:.3s all ease-in-out;
}
/* 拖拽時用jQuery為其添加邊框樣式的class */
.holder-ondrag{
border:20px dotted #d45700;
}
</style>
<body>
<h1>Write to ./message.txt</h1>
<p>輸入一段文字:</p>
<textarea rows="10" id="textarea_t"></textarea>
<button id="btn_write">Write</button>
<hr>
<h1>Drag file to open it.</h1>
<div id="holder" class="holder">
Drag sth. in here
</div>
</body>
<script>
// You can also require other files to run in this process
require('./renderer.js')
</script>
</html>
修改渲染進程文件renderer.js
:
這里提供兩種寫法,第一種是jQuery,另一種是原生Js寫法。
jQuery:
// This file is required by the index.html file and will
// be executed in the renderer process for that window.
// All of the Node.js APIs are available in this process.
var fs=require('fs'),
textarea=$("#textarea_t"),
holder=$("#holder"),
button=$("#btn_write")
;
button.click(function writeFile(){
console.log(textarea.val());
fs.writeFileSync(
'message.txt',
textarea.val(),
'utf8'
);
});
holder.on("dragenter dragover",function(event){
// 重寫ondragover 和 ondragenter 使其可放置
event.preventDefault();
holder.addClass("holder-ondrag");
holder.text("Release Mouse");
});
holder.on("dragleave",function(event){
event.preventDefault();
holder.removeClass("holder-ondrag");
holder.text("Please Drag sth. in here");
});
holder.on("drop",function(event){
// 調用 preventDefault() 來避免瀏覽器對數據的默認處理(drop 事件的默認行為是以鏈接形式打開)
event.preventDefault();
console.log(event.dataTransfer);
// 原生語句如下,但引進jquery后要更改
// var file=event.dataTransfer.files[0];
// 原因:
// 在jquery中,最終傳入事件處理程序的 event 其實已經被 jQuery 做過標準化處理,
// 其原有的事件對象則被保存于 event 對象的 originalEvent 屬性之中,
// 每個 event 都是 jQuery.Event 的實例
// 應該這樣寫:
var efile=event.originalEvent.dataTransfer.files[0];
holder.removeClass("holder-ondrag");
fs.readFile(efile.path,"utf8",function(err,data){
if(err) throw err;
console.log(data);
// holder.text(data);
//讀取文件的內容,如果使用jquery的text()或html(),val()都不能保留格式
//而使用Obj.innerText 則可以。那么把holder的jquery對象轉為dom對象
holder[0].innerText=data;
});
console.log();
return false;
});
原生 Js :
//原生Js寫法
var fs=require('fs'),
textarea=document.getElementById("textarea_t"),
holder=document.getElementById("holder"),
button=document.getElementById("btn_write")
;
holder.ondragenter=holder.ondragover=function(event){
// 重寫ondragover 和 ondragenter 使其可放置
event.preventDefault();
holder.className("holder-ondrag");
holder.innerText="Release Mouse";
};
holder.ondragleave=function(event){
event.preventDefault();
holder.className(" ");
holder.innerText="Please Drag sth. in here";
};
holder.ondrop=function(event){
// 調用 preventDefault() 來避免瀏覽器對數據的默認處理
//(drop 事件的默認行為是以鏈接形式打開)
event.preventDefault();
var file=event.dataTransfer.files[0];
fs.readFile(file.path,"utf8",function(err,data){
console.log(data);
holder.innerText=data;
});
}
如果去掉注釋的話,還是jQuery更加精簡方便。
對于用electron構建桌面端應用的話,若不用React.js、Angular.js等框架,還涉及到頻繁的DOM操作,建議還是直接上 jQuery會比較方便吧。
跑是跑起來了,但是還要說一下主線程文件 main.js
核心的代碼大致如下:
//引用electron的模塊
const electron = require('electron')
const app = electron.app
const BrowserWindow = electron.BrowserWindow
const path = require('path')
const url = require('url')
let mainWindow
function createWindow () {
// 創建窗口
mainWindow = new BrowserWindow({width: 800, height: 600})
// 通過 url 加載主頁
mainWindow.loadURL(url.format({
pathname: path.join(__dirname, 'index.html'),
protocol: 'file:',
slashes: true
}))
// 在打開時啟用開發者工具
// mainWindow.webContents.openDevTools()
// 監聽窗口是否關閉
mainWindow.on('closed', function () {
mainWindow = null
})
}
待添加:
功能上還能在應用Menu上加個 File - Open
不過也不難,調用一些API就差不多了
暫時就到這里
應用打包
這個待填坑,遲點再更
總結體會
electron.js就是給你的網站加個webkit內核的瀏覽器,如果你的應用并不需要調用到系統的API,還是老老實實直接在web上開發。從設計的時候就要深入考慮到要涉及哪些系統的API。
不過應用的啟動速度以及體積大小的情況還是存在著一些弊端的。
結合下面的API利器,構建桌面端應用基本就夠了
Electron API 帶DEMO的中文文檔:
https://github.com/demopark/electron-api-demos-Zh_CN
Node.js API 中文文檔:
http://nodejs.cn/api/