electron + jQuery +node.js 快速上手之实现写入文件、拖拽打开文件并读取内容的功能

导言

近来对electron有点感兴趣,奈何干啃官方文档实在难受,还是直接从demo入手会比较好。受到一两个教程的启发,然后自己瞎捣鼓一下。

说明

利用Electron.js构建一个有以下功能的桌面端应用:

  • 实现简单的获取文本框输入的内容并保存为文件
  • 能够通过拖拽文件来读取其中的信息

应用界面

因为只是demo ,为了方面,就只是加基础样式了,将就着看。

应用界面.png
输入文字.png
结果.png
拖拽文件.png
读取并查看内容.png

快速开始:

准备工作

以官方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/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,761评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,953评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,998评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,248评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,130评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,145评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,550评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,236评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,510评论 1 291
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,601评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,376评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,247评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,613评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,911评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,191评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,532评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,739评论 2 335

推荐阅读更多精彩内容