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/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容