温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

原生JavaScript如何实现具有进度监听的文件上传预览组件

发布时间:2021-09-30 10:57:25 来源:亿速云 阅读:160 作者:柒染 栏目:web开发

本篇文章为大家展示了原生JavaScript如何实现具有进度监听的文件上传预览组件,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

原生js的使用

通过面向对象的方式实现一个文件上传预览的组件,该组件利用FileReader来实现文件在前端的解析,预览,读取进度等功能,并对外暴露相应api来实现用户自定义的需求,比如文件上传,进度监听,自定义样式,读取成功回调等。

组件设计架构如下:

原生JavaScript如何实现具有进度监听的文件上传预览组件

涉及的核心知识点如下:

  1. 闭包:减少变量污染,缩短变量查找范围

  2. 自执行函数

  3. file API:对文件进行读取,解析,监控文件事件

  4. DocumentFragment API:主要用来优化dom操作

  5. minix :用来实现对象混合

  6. 正则表达式:匹配文件类型

  7. class :类组件

github地址

用原生js实现具有进度监听的文件上传预览组件

Demo演示

原生JavaScript如何实现具有进度监听的文件上传预览组件
原生JavaScript如何实现具有进度监听的文件上传预览组件

原生JavaScript如何实现具有进度监听的文件上传预览组件

原生JavaScript如何实现具有进度监听的文件上传预览组件

使用:

<div id="test"></div> <script src="./js/xjFile.js"></script> <script>     new xjFile({         el: '#test', // 不填则直接默认挂在body上         accept: 'image/png', // 可选         clsName: 'xj-wrap', // 可选         beforeUpload: function(e) { console.log(e) }, // 可选         onProgress: function(e) { console.log(e) }, // 可选         onLoad: function(e) { console.log(e) }, // 可选         onError: function(e) { console.error('文件读取错误', e) } // 可选     }); </script>

css代码:

.xj-wrap {             position: relative;             display: inline-block;             border: 1px dashed #888;             width: 200px;             height: 200px;             border-radius: 6px;             overflow: hidden;         }         .xj-wrap::before {             content: '+';             font-size: 36px;             position: absolute;             transform: translate(-50%, -50%);             left: 50%;             top: 50%;             color: #ccc;         }         .xj-wrap .xj-pre-img {             width: 100%;             height: 100%;             background-repeat: no-repeat;             background-position: center center;             background-size: 100%;         }         .xj-file {             position: absolute;             left: 0;             right: 0;             bottom: 0;             top: 0;             opacity: 0;             cursor: pointer;         }

js代码:

(function(win, doc){     function xjFile(opt) {         var defaultOption = {             el: doc.body,             accept: '*', // 格式按照'image/jpg,image/gif'传             clsName: 'xj-wrap',             beforeUpload: function(e) { console.log(e) },             onProgress: function(e) { console.log(e) },             onLoad: function(e) { console.log(e) },             onError: function(e) { console.error('文件读取错误', e) }         };          // 获取dom         if(opt.el) {             opt.el = typeof opt.el === 'object' ? opt.el : document.querySelector(opt.el);         }          this.opt = minix(defaultOption, opt);         this.value = '';         this.init();     }      xjFile.prototype.init = function() {         this.render();         this.watch();     }      xjFile.prototype.render = function() {         var fragment = document.createDocumentFragment(),             file = document.createElement('input'),             imgBox = document.createElement('div');         file.type = 'file';         file.accept = this.opt.accept || '*';         file.className = 'xj-file';         imgBox.className = 'xj-pre-img';         // 插入fragment         fragment.appendChild(file);         fragment.appendChild(imgBox);         // 给包裹组件设置class         this.opt.el.className = this.opt.clsName;         this.opt.el.appendChild(fragment);     }      xjFile.prototype.watch = function() {         var ipt = this.opt.el.querySelector('.xj-file');         var _this = this;         ipt.addEventListener('change', (e) => {             var file = ipt.files[0];              // 给组件赋值             _this.value = file;              var fileReader = new FileReader();              // 读取文件开始时触发             fileReader.onloadstart = function(e) {                 if(_this.opt.accept !== '*' && _this.opt.accept.indexOf(file.type.toLowerCase()) === -1) {                     fileReader.abort();                     _this.opt.beforeUpload(file, e);                     console.error('文件格式有误', file.type.toLowerCase());                 }             }              // 读取完成触发的事件             fileReader.onload = (e) => {                 var imgBox = this.opt.el.querySelector('.xj-pre-img');                 if(isImage(file.type)) {                     imgBox.innerHTML = '';                     imgBox.style.backgroundImage = 'url(' + fileReader.result + ')';                 } else {                     imgBox.innerHTML = fileReader.result;                 }                                  imgBox.title = file.name;                  this.opt.onLoad(e);             }              // 文件读取出错事件             fileReader.onerror = (e) => {                 this.opt.onError(e);             }              // 文件读取进度事件             fileReader.onprogress = (e) => {                 this.opt.onProgress(e);             }              isImage(file.type) ? fileReader.readAsDataURL(file) : fileReader.readAsText(file);                      }, false);     }      // 清除ipt和组件的值,支持链式调用     xjFile.prototype.clearFile = function() {         this.opt.el.querySelector('.xj-file').value = '';         this.value = '';         return this     }      // 简单对象混合     function minix(source, target) {         for(var key in target) {             source[key] = target[key];         }         return source     }      // 检测图片类型     function isImage(type) {         var reg = /(image\/jpeg|image\/jpg|image\/gif|image\/png)/gi;         return reg.test(type)     }      // 将方法挂载到window上     win.xjFile = xjFile;  })(window, document);

class版(后期规划)

class版的也很简单,大致框架如下,感兴趣的朋友可以实现一下呦~

class XjFile {     constructor(opt) {      }      init() {      }      watch() {      }      render() {      }      clearFile() {      }      minix(source, target) {              }      isImage(type) {              } }

上述内容就是原生JavaScript如何实现具有进度监听的文件上传预览组件,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注亿速云行业资讯频道。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI