js之FileReader学习总结

来源:互联网 发布:股票历史交易数据查询 编辑:程序博客网 时间:2024/06/05 19:34

基本使用

var reader = new FileReader();// 文件输入控件添加的第一个文件var file = $('file').files[0]; // 读取结束时触发reader.onload = e => {  console.log(e.target.result);};if (file && file.type.match(/text\/\w+/)) {  reader.readAsText(file);}

乍一看, 也就那么回事, 其实也就那么回事, 不过我们还是看看细节.

原生支持的事件

事件名称 说明 注意 onabort 读取被中止时触发 onerror 读取发生错误时触发 onload 读取完成后触发 一般在这里处理逻辑 onloadend 读取结束后触发, 无论成功还是失败 感觉应该叫oncomplete比较合适 onloadstart 读取操作将要开始之前调用 onprogress 读取过程中周期性触发 做进度条用

原生带有的方法

方法 说明 注意 void abort(); 中止读取 void readAsArrayBuffer(in Blob blob); 以ArrayBuffer的方式读取 void readAsBinaryString(in Blob blob); 以二进制字符串的形式读取 void readAsDataURL(in Blob blob); 以data: URL的形式读取 void readAsText(in Blob blob, [encoding); 以纯文本的形式读取, 还有可靠的编码作为第二个参数 默认编码UTF-8

一个比较全面的例子

实现的功能:

  • 通过file控件预览文本, 图片
  • 非文本, 图片的以二进制串输出
  • 拖拽上述文件实现预览

包含的知识点:

  • readAsText方法的使用
  • readAsDataURL方法的使用
  • readAsBinaryString方法的使用
  • 一些Promise的用法也穿插其中
  • 简单的拖拽用法

在线演示

为了方便观看, 这里也把代码帖上:

<!DOCTYPE html><html lang="zh-CN"><head>  <meta charset="UTF-8">  <meta name="viewport" content="width=device-width, initial-scale=1.0">  <meta http-equiv="X-UA-Compatible" content="ie=edge">  <title>FileReader Learning</title></head><body>  <div class="container">    <form novalidate>      <div class="avatars-row" style="margin: 10px;">        <label>选择文件:           <input type="file" name="avatars" id="attachment" accept="*/*" multiple></input>        </label>      </div>      <div class="result" id="result" style="overflow: auto; border: 1px solid cyan; height: 300px;"></div>    </form>  </div>  <script>    (function (window, doc, undefined) {      function $(id) {        return doc.getElementById(id);      }      let App = {        createFileReader: () => {          if (typeof FileReader === "undefined") {            throw new Error("FileReader is not avaliable");          }          return new FileReader();        },        /**         * @return FileList         */        getFiles: () => {          var attachment = $("attachment"),            files = attachment.files;          return files || new Error("no file uploaded");        },        /**         * 统一的读取接口         */        read: function(api, file, callback) {          let self = this;          return new Promise((resolve, reject) => {            let reader = self.createFileReader();            reader.onload = e => {              resolve(e.target.result);            };            reader.onerror = e => {              reject("read error");            };            reader.onabort = e => {              reject("abort error");            };            // size <= 1M            if (file && file.size > 1 * 1024 * 1024) {              reject('file is too large');              return;            }            reader[api](file);          });        },        onFileChange: function(callback) {          let self = this;          $("attachment").onchange = function (e) {            callback(self.getFiles());          };        },        onDrop: function() {          let self = this;          let resultContainer = $('result');          document.ondragover = e => {            e.preventDefault();          };          document.ondrop = e => {            e.preventDefault();          };          resultContainer.ondragend = e => {            e.preventDefault();          };          resultContainer.ondrop = e => {            e.preventDefault();            let files = e.dataTransfer.files;            self.handleAll(files);          };        },        handleFiles: function(files) {          let self = this;          let p;          let ret = [];          // FileList转数组          [].slice.call(files).forEach(function(file, i) {            const type = file.type;            switch (true) {              case /text\/\w+/.test(type):                p = self.read("readAsText", file);                break;              case /image\/\w+/.test(type):                p = self.read("readAsDataURL", file);                break;              default:                p = self.read("readAsBinaryString", file);                break;            }            ret.push(p);          });          return ret;        },        init: function() {          var self = this;          self.onDrop();          // 这里的onFileChange不能写成Promise, 不然只会第一次有效, 因为状态已经是fulfilled了          self.onFileChange(files => {            self.handleAll(files);          });        },        handleAll: function(files) {          let self = this;          Promise.all(self.handleFiles(files))            .then(results => {              self.showResults(results);            })            .catch(err => {              console.log(err);            });        },        showResults: results => {          console.log(results);          let resultContainer = $("result");          results.forEach((result, i) => {            // alert(3);            switch (true) {              case result.indexOf("data:image/") >= 0:                resultContainer.innerHTML += `<div><img src="${result}"></div>`;                break;              default:                resultContainer.innerHTML += `<p>${result}<p>`;                break;            }          });        }      };      App.init();    })(window, document);  </script></body></html>

欢迎补充!