@Dale-Lin
2020-07-18T12:00:01.000000Z
字数 3483
阅读 1121
web_APIs
使用 File API 让用户选择本地文件,然后读取这些文件,使用 <input type="file"> 或是拖拽选择本地文件。
multiple 属性可让用户选择多个文件:
<input type="file" id="fileInput" mutiple>
对于一个文件选择框:
<input type="file" id="fileInput">
通过其 files 属性获取一个 FileList 对象:
const seletedFiles = document.getElementById('fileInput')const firstFile = seletedFiles[0]
onchange 事件处理函数传入 this.files 作为参数:
// 注意属性是字符串<input type="file" id="fileInput" onchange="handleFiles(e)">
使用 addEventListener 添加 onchange 事件处理函数:
function handleFiles(e) {// ...const fileList = this.files}const inputElem = document.getElementById('fileInput')inputElem.addEventListener("change", handleFiles, false)
FileList 内文件的属性每个 file 对象具有以下属性:
name size type 将输入框设置 display:none,然后在自己定义的 API 上调用输入框的 click() 方法来触发。
或者使用 <label for="fileInput">。 元素
如果是 a 标签记得取消默认行为。
同理,先创建一个可拖拽区域,然后调用 click() 函数:
var dropbox;dropbox = document.getElementById('dropbox');dropbox.addEventListener('dragenter', dragenter, false);dropbox.addEventListener('dragover', dragover, false);dropbox.addEventListener('drop', drop, false);
添加 dragenter、dragover、drop 事件处理函数:
function dragenter(e) {e.stopPropagation();e.preventDefault();}function dragover(e) {e.stopPropagation();e.preventDefault();}// 重点function drop(e) {e.stopPropagation();e.preventDefault();// DragEvent.dataTransfer 属性// 包含 drag 操作的数据对象var dt = e.dataTransfer;var files = dt.files;handleFiles(files);}
FileReader 对象允许 web 应用异步读取文件(File 对象或者 Blob 对象):
// 创建const reader = new FileReader();reader.readAsDataURL(file);
FileReader.error FileReader.result FileReader.readyState FileReader.onload FileReader.onabort FileReader.onprogress Blob 时触发。FileReader.abortFileReader.readAsArrayBufferFileReader.readAsBinaryStringFileReader.readAsDataURLFileReader.readAsText
function handleFiles(files) {var preview = document.getElementById('preview');for (var i = 0; i < files.length; i++) {var file = files[i];var imgType = /^image\//;if(!imgType.test(file.type)) continue;var img = document.createElement('img');img.classList.add('obj');// file 属性使 img 具有一个 File 对象// 用以拿到稍后需要实际上传的图片文件img.file = file;preview.appendChild(img);var reader = new FileReader();// fileReader.result 返回文件的内容// 格式取决于读取方法// 这里返回 data:URLreader.onload = ((aImg) => {return function(e){aImg.src = e.target.result}})(img);// 在后台开始读取 filereader.readAsDataURL(file)}}
使用 window.URL.createObjectURL() 方法创建用来引用某数据的 URL 字符串:
var objectURL = window.URL.createObjectURL(fileObj);
使用完后必须使用
window.URL.revokeObjectURL(objectURL)释放引用!
上例缩略图中,img 的 file 属性保存了所有图片的 file 对象(不然要重新获取):
function sendFiles() {var imgs = document.querySelectorAll('.obj');for (var i = 0; i < imgs.length; i++) {new FileUpload(imgs[i], imgs[i].file);}}function FileUpload(img, file){var reader = new FileReader();// canvas,加载的 loading 背景this.ctrl = createThrobber(img);var xhr = new XMLHttpRequest();this.xhr = xhr;var self = this;this.xhr.upload.addEventListener('progress', function(e){if (e.lengthComputable) {var precentage = Math.round((e.loaded * 100) / e.total);self.ctrl.update(percentage);}}, false);xhr.upload.addEventListener('load', function(e) {self.ctrl.update(100);var canvas = self.ctrl.ctx.canvas;canvas.parentNode.removeChild(canvas);}, false);xhr.open("POST", "http://demos.hacks.mozilla.org/paul/demos/resources/webservices/devnull.php");xhr.overrideMimeType('text/plain; charset=x-user-defined-binary');reader.onload = function(evt) {xhr.send(evt.target.result);};reader.readAsArrayBuffer(file);}