[关闭]
@Dale-Lin 2020-07-18T20:00:01.000000Z 字数 3483 阅读 789

File

web_APIs


使用 File API 让用户选择本地文件,然后读取这些文件,使用 <input type="file"> 或是拖拽选择本地文件。

选择多个文件

multiple 属性可让用户选择多个文件:

  1. <input type="file" id="fileInput" mutiple>

获取已选择的 files

对于一个文件选择框:

  1. <input type="file" id="fileInput">

通过其 files 属性获取一个 FileList 对象:

  1. const seletedFiles = document.getElementById('fileInput')
  2. const firstFile = seletedFiles[0]

在 onchenge 中获取

onchange 事件处理函数传入 this.files 作为参数:

  1. // 注意属性是字符串
  2. <input type="file" id="fileInput" onchange="handleFiles(e)">

使用 addEventListener 添加 onchange 事件处理函数:

  1. function handleFiles(e) {
  2. // ...
  3. const fileList = this.files
  4. }
  5. const inputElem = document.getElementById('fileInput')
  6. inputElem.addEventListener("change", handleFiles, false)

获取 FileList 内文件的属性

每个 file 对象具有以下属性:

在另一处触发隐藏的选择输入框

将输入框设置 display:none,然后在自己定义的 API 上调用输入框的 click() 方法来触发。

或者使用 <label for="fileInput">。 元素

如果是 a 标签记得取消默认行为。

使用拖拽

同理,先创建一个可拖拽区域,然后调用 click() 函数:

  1. var dropbox;
  2. dropbox = document.getElementById('dropbox');
  3. dropbox.addEventListener('dragenter', dragenter, false);
  4. dropbox.addEventListener('dragover', dragover, false);
  5. dropbox.addEventListener('drop', drop, false);

添加 dragenterdragoverdrop 事件处理函数:

  1. function dragenter(e) {
  2. e.stopPropagation();
  3. e.preventDefault();
  4. }
  5. function dragover(e) {
  6. e.stopPropagation();
  7. e.preventDefault();
  8. }
  9. // 重点
  10. function drop(e) {
  11. e.stopPropagation();
  12. e.preventDefault();
  13. // DragEvent.dataTransfer 属性
  14. // 包含 drag 操作的数据对象
  15. var dt = e.dataTransfer;
  16. var files = dt.files;
  17. handleFiles(files);
  18. }

FlieReader

FileReader 对象允许 web 应用异步读取文件(File 对象或者 Blob 对象):

  1. // 创建
  2. const reader = new FileReader();
  3. reader.readAsDataURL(file);

属性

事件处理

方法


例子:显示用户选择的图片的缩略图

  1. function handleFiles(files) {
  2. var preview = document.getElementById('preview');
  3. for (var i = 0; i < files.length; i++) {
  4. var file = files[i];
  5. var imgType = /^image\//;
  6. if(!imgType.test(file.type)) continue;
  7. var img = document.createElement('img');
  8. img.classList.add('obj');
  9. // file 属性使 img 具有一个 File 对象
  10. // 用以拿到稍后需要实际上传的图片文件
  11. img.file = file;
  12. preview.appendChild(img);
  13. var reader = new FileReader();
  14. // fileReader.result 返回文件的内容
  15. // 格式取决于读取方法
  16. // 这里返回 data:URL
  17. reader.onload = ((aImg) => {return function(e){aImg.src = e.target.result}})(img);
  18. // 在后台开始读取 file
  19. reader.readAsDataURL(file)
  20. }
  21. }

使用 Object URL

使用 window.URL.createObjectURL() 方法创建用来引用某数据的 URL 字符串:

  1. var objectURL = window.URL.createObjectURL(fileObj);

使用完后必须使用 window.URL.revokeObjectURL(objectURL) 释放引用!

上传一个用户选择的文件

上例缩略图中,img 的 file 属性保存了所有图片的 file 对象(不然要重新获取):

  1. function sendFiles() {
  2. var imgs = document.querySelectorAll('.obj');
  3. for (var i = 0; i < imgs.length; i++) {
  4. new FileUpload(imgs[i], imgs[i].file);
  5. }
  6. }
  7. function FileUpload(img, file){
  8. var reader = new FileReader();
  9. // canvas,加载的 loading 背景
  10. this.ctrl = createThrobber(img);
  11. var xhr = new XMLHttpRequest();
  12. this.xhr = xhr;
  13. var self = this;
  14. this.xhr.upload.addEventListener('progress', function(e){
  15. if (e.lengthComputable) {
  16. var precentage = Math.round((e.loaded * 100) / e.total);
  17. self.ctrl.update(percentage);
  18. }
  19. }, false);
  20. xhr.upload.addEventListener('load', function(e) {
  21. self.ctrl.update(100);
  22. var canvas = self.ctrl.ctx.canvas;
  23. canvas.parentNode.removeChild(canvas);
  24. }, false);
  25. xhr.open("POST", "http://demos.hacks.mozilla.org/paul/demos/resources/webservices/devnull.php");
  26. xhr.overrideMimeType('text/plain; charset=x-user-defined-binary');
  27. reader.onload = function(evt) {
  28. xhr.send(evt.target.result);
  29. };
  30. reader.readAsArrayBuffer(file);
  31. }
  1. 在 FileUpload 函数内编写 XHR 对象的内容和上传处理函数(onprogress、onload)。
  2. 使用一个 FileReader 读取 file,再上传读取完成后的 ArrayBuffer。
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注