js之FileReader学习总结

基本使用

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的用法也穿插其中
  • 简单的拖拽用法

在线演示

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


<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 Learningtitle>
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 += `
${result}">
`
; break; default: resultContainer.innerHTML += `

${result}

`; break; } }); } }; App.init(); })(window, document); script> body> html>

欢迎补充!

你可能感兴趣的:(JavaScript)