自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

前端進(jìn)階:原生JavaScript實(shí)現(xiàn)具有進(jìn)度監(jiān)聽的文件上傳預(yù)覽組件

開發(fā) 前端
本文主要介紹如何使用原生js,通過面向?qū)ο蟮姆绞綄?shí)現(xiàn)一個(gè)文件上傳預(yù)覽的組件,該組件利用FileReader來實(shí)現(xiàn)文件在前端的解析,預(yù)覽,讀取進(jìn)度等功能,并對外暴露相應(yīng)api來實(shí)現(xiàn)用戶自定義的需求,比如文件上傳,進(jìn)度監(jiān)聽,自定義樣式,讀取成功回調(diào)等。

[[385115]]

本文主要介紹如何使用原生js,通過面向?qū)ο蟮姆绞綄?shí)現(xiàn)一個(gè)文件上傳預(yù)覽的組件,該組件利用FileReader來實(shí)現(xiàn)文件在前端的解析,預(yù)覽,讀取進(jìn)度等功能,并對外暴露相應(yīng)api來實(shí)現(xiàn)用戶自定義的需求,比如文件上傳,進(jìn)度監(jiān)聽,自定義樣式,讀取成功回調(diào)等。

組件設(shè)計(jì)架構(gòu)如下:

涉及的核心知識點(diǎn)如下:

  1. 閉包:減少變量污染,縮短變量查找范圍
  2. 自執(zhí)行函數(shù)
  3. file API:對文件進(jìn)行讀取,解析,監(jiān)控文件事件
  4. DocumentFragment API:主要用來優(yōu)化dom操作
  5. minix :用來實(shí)現(xiàn)對象混合
  6. 正則表達(dá)式:匹配文件類型
  7. class :類組件

github地址

用原生js實(shí)現(xiàn)具有進(jìn)度監(jiān)聽的文件上傳預(yù)覽組件

Demo演示


使用:

  1. <div id="test"></div> 
  2. <script src="./js/xjFile.js"></script> 
  3. <script> 
  4.     new xjFile({ 
  5.         el: '#test', // 不填則直接默認(rèn)掛在body上 
  6.         accept: 'image/png', // 可選 
  7.         clsName: 'xj-wrap', // 可選 
  8.         beforeUpload: function(e) { console.log(e) }, // 可選 
  9.         onProgress: function(e) { console.log(e) }, // 可選 
  10.         onLoad: function(e) { console.log(e) }, // 可選 
  11.         onError: function(e) { console.error('文件讀取錯(cuò)誤', e) } // 可選 
  12.     }); 
  13. </script> 

css代碼:

  1. .xj-wrap { 
  2.             position: relative
  3.             display: inline-block; 
  4.             border: 1px dashed #888; 
  5.             width: 200px; 
  6.             height: 200px; 
  7.             border-radius: 6px; 
  8.             overflow: hidden; 
  9.         } 
  10.         .xj-wrap::before { 
  11.             content: '+'
  12.             font-size: 36px; 
  13.             position: absolute
  14.             transform: translate(-50%, -50%); 
  15.             left: 50%; 
  16.             top: 50%; 
  17.             color: #ccc; 
  18.         } 
  19.         .xj-wrap .xj-pre-img { 
  20.             width: 100%; 
  21.             height: 100%; 
  22.             background-repeat: no-repeat; 
  23.             background-position: center center; 
  24.             background-size: 100%; 
  25.         } 
  26.         .xj-file { 
  27.             position: absolute
  28.             left: 0; 
  29.             right: 0; 
  30.             bottom: 0; 
  31.             top: 0; 
  32.             opacity: 0; 
  33.             cursor: pointer; 
  34.         } 

js代碼:

  1. (function(win, doc){ 
  2.     function xjFile(opt) { 
  3.         var defaultOption = { 
  4.             el: doc.body, 
  5.             accept: '*', // 格式按照'image/jpg,image/gif'傳 
  6.             clsName: 'xj-wrap'
  7.             beforeUpload: function(e) { console.log(e) }, 
  8.             onProgress: function(e) { console.log(e) }, 
  9.             onLoad: function(e) { console.log(e) }, 
  10.             onError: function(e) { console.error('文件讀取錯(cuò)誤', e) } 
  11.         }; 
  12.  
  13.         // 獲取dom 
  14.         if(opt.el) { 
  15.             opt.el = typeof opt.el === 'object' ? opt.el : document.querySelector(opt.el); 
  16.         } 
  17.  
  18.         this.opt = minix(defaultOption, opt); 
  19.         this.value = ''
  20.         this.init(); 
  21.     } 
  22.  
  23.     xjFile.prototype.init = function() { 
  24.         this.render(); 
  25.         this.watch(); 
  26.     } 
  27.  
  28.     xjFile.prototype.render = function() { 
  29.         var fragment = document.createDocumentFragment(), 
  30.             file = document.createElement('input'), 
  31.             imgBox = document.createElement('div'); 
  32.         file.type = 'file'
  33.         file.accept = this.opt.accept || '*'
  34.         file.className = 'xj-file'
  35.         imgBox.className = 'xj-pre-img'
  36.         // 插入fragment 
  37.         fragment.appendChild(file); 
  38.         fragment.appendChild(imgBox); 
  39.         // 給包裹組件設(shè)置class 
  40.         this.opt.el.className = this.opt.clsName; 
  41.         this.opt.el.appendChild(fragment); 
  42.     } 
  43.  
  44.     xjFile.prototype.watch = function() { 
  45.         var ipt = this.opt.el.querySelector('.xj-file'); 
  46.         var _this = this; 
  47.         ipt.addEventListener('change', (e) => { 
  48.             var file = ipt.files[0]; 
  49.  
  50.             // 給組件賦值 
  51.             _this.value = file; 
  52.  
  53.             var fileReader = new FileReader(); 
  54.  
  55.             // 讀取文件開始時(shí)觸發(fā) 
  56.             fileReader.onloadstart = function(e) { 
  57.                 if(_this.opt.accept !== '*' && _this.opt.accept.indexOf(file.type.toLowerCase()) === -1) { 
  58.                     fileReader.abort(); 
  59.                     _this.opt.beforeUpload(file, e); 
  60.                     console.error('文件格式有誤', file.type.toLowerCase()); 
  61.                 } 
  62.             } 
  63.  
  64.             // 讀取完成觸發(fā)的事件 
  65.             fileReader.onload = (e) => { 
  66.                 var imgBox = this.opt.el.querySelector('.xj-pre-img'); 
  67.                 if(isImage(file.type)) { 
  68.                     imgBox.innerHTML = ''
  69.                     imgBox.style.backgroundImage = 'url(' + fileReader.result + ')'
  70.                 } else { 
  71.                     imgBox.innerHTML = fileReader.result; 
  72.                 } 
  73.                  
  74.                 imgBox.title = file.name
  75.  
  76.                 this.opt.onLoad(e); 
  77.             } 
  78.  
  79.             // 文件讀取出錯(cuò)事件 
  80.             fileReader.onerror = (e) => { 
  81.                 this.opt.onError(e); 
  82.             } 
  83.  
  84.             // 文件讀取進(jìn)度事件 
  85.             fileReader.onprogress = (e) => { 
  86.                 this.opt.onProgress(e); 
  87.             } 
  88.  
  89.             isImage(file.type) ? fileReader.readAsDataURL(file) : fileReader.readAsText(file); 
  90.              
  91.         }, false); 
  92.     } 
  93.  
  94.     // 清除ipt和組件的值,支持鏈?zhǔn)秸{(diào)用 
  95.     xjFile.prototype.clearFile = function() { 
  96.         this.opt.el.querySelector('.xj-file').value = ''
  97.         this.value = ''
  98.         return this 
  99.     } 
  100.  
  101.     // 簡單對象混合 
  102.     function minix(source, target) { 
  103.         for(var key in target) { 
  104.             source[key] = target[key]; 
  105.         } 
  106.         return source 
  107.     } 
  108.  
  109.     // 檢測圖片類型 
  110.     function isImage(type) { 
  111.         var reg = /(image\/jpeg|image\/jpg|image\/gif|image\/png)/gi; 
  112.         return reg.test(type) 
  113.     } 
  114.  
  115.     // 將方法掛載到window上 
  116.     win.xjFile = xjFile; 
  117.  
  118. })(window, document); 

class版(后期規(guī)劃)

class版的也很簡單,大致框架如下,感興趣的朋友可以實(shí)現(xiàn)一下呦~

  1. class XjFile { 
  2.     constructor(opt) { 
  3.  
  4.     } 
  5.  
  6.     init() { 
  7.  
  8.     } 
  9.  
  10.     watch() { 
  11.  
  12.     } 
  13.  
  14.     render() { 
  15.  
  16.     } 
  17.  
  18.     clearFile() { 
  19.  
  20.     } 
  21.  
  22.     minix(source, target) { 
  23.          
  24.     } 
  25.  
  26.     isImage(type) { 
  27.          
  28.     } 

總結(jié)

該組件仍有需要完善的地方,在后期使用中,會慢慢更新,優(yōu)化,歡迎大家提出寶貴的建議。

 

責(zé)任編輯:姜華 來源: 趣談前端
相關(guān)推薦

2009-11-24 15:23:50

PHP文件上傳進(jìn)度條

2009-07-21 14:49:55

XmlHttpRequ文件上傳進(jìn)度條

2020-04-02 20:07:17

前端vuenote.js

2021-11-29 08:50:57

Javascript存儲函數(shù)

2012-03-27 11:08:23

Java

2021-06-01 05:15:36

JavaScript 前端大文件并發(fā)上傳

2020-03-06 10:05:59

前端Javascript代碼

2020-10-20 11:12:11

Nodejs

2016-11-09 10:28:36

Nodejs文件上傳express+mul

2009-11-16 14:27:45

PHP上傳文件進(jìn)度

2011-12-30 09:49:36

Silverlight

2017-12-01 10:13:42

前端操作上傳

2009-07-02 13:31:13

JSP組件

2021-05-07 08:20:52

前端開發(fā)技術(shù)熱點(diǎn)

2015-05-07 15:13:22

JS實(shí)現(xiàn)JQueryJQuery

2009-07-06 17:11:38

Servlet文件上傳

2021-01-04 14:41:28

開發(fā)前端工具

2021-02-05 08:18:29

JavaScript開發(fā)代碼

2009-07-14 17:20:31

Webwork文件上傳

2017-08-08 08:45:44

前端文件斷點(diǎn)續(xù)傳
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號