@Dale-Lin
2020-07-18T20:00:01.000000Z
字数 3483
阅读 789
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.abort
FileReader.readAsArrayBuffer
FileReader.readAsBinaryString
FileReader.readAsDataURL
FileReader.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:URL
reader.onload = ((aImg) => {return function(e){aImg.src = e.target.result}})(img);
// 在后台开始读取 file
reader.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);
}