前言
前端工作过程中有这么一个基本需求,要求将图片从本地选择上传到服务器,同时在本地进行预览。
这对于我这只小菜鸟来说也是难啊,为了预防写完了就忘,以及知识太过杂乱而不系统,在这里重新整理一下。
正文
预览代码
二话不说,先把成功预览图片的代码贴上来。
在这里我用的是vue,所以图片路径是经过vue数据绑定的。
// .html
// input file输入框可以设置opacity为0,然后绝对定位覆盖
<img :src="head_img" alt="头像">
<input type="file" @change="onFileChange" id="file">
// .js
data() {
return {
header_img: ''
}
},
// 图片上传主要是靠FileReader对象
methods: {
onFileChange() {
if (typeof FileReader === 'undefined') {
console.log('false');
return false;
}
var file = document.getElementById('file').files[0];
var reader = new FileReader();
reader.readAsDataURL(file);
var vm = this;
reader.onload = function(e) {
vm.image = e.target.result;
}
}
}
初学者看到上述代码可能会有些不了解的地方,这样就让我们带着问题阅读下述知识点~
在Web应用中使用文件
在学习使用FileReader对象时,首先需要先了解在Web应用中应该如何使用文件。
使用在HTML5中添加到DOM的File API,现在可以让Web内容要求用户选择本地文件,然后读取这些文件的内容。
此选择可以通过使用HTML<input>
标签或者拖放来实现。
1.访问所选的文件
请看下面的HTML:
<input type="file" id="input">
<input type="file" id="input" multiple >
通过File API,我们可以在用户选取一个或者多个文件之后,访问到代表了所选文件的一个或多个File对象,这些对象被全部包含在一个FileList对象中。
PS:
所以这里document.getElementById('file').files
得到的是一个FileList对象。
如果你得到一个“files is undefined”错误,那么就是你没有选择正确的HTML元素
2.在一个change事件发生时,访问选择的文件
另外,还可以在input元素上的change事件触发时再访问它的FileList属性(但并非强制性):
<input type="file" id="input" onchange="handleFiles(this.files)">
当用户成功选取若干个文件后,handleFiles()函数会被调用,且一个代表用户所选择的文件包含了File对象的FileList对象会作为参数传入该函数。
如果想选择多个文件,记得要在input元素上加上multiple属性:
<input type="file" id="input" multiple onchange="handleFiles(this.files)">
在用户选择了多个文件的情况下,传入handleFiles()函数的文件列表将会包含多个File对象,每个File对象对应一个真实的文件。
PS:当然也可以通过动态添加change事件监听器
var inputElement = document.getElementById("inputField");
inputElement.addEventListener("change", handleFiles, false);
function handleFiles() {
var fileList = this.files;
}
3.获取所选文件的信息
用户将所选择的文件都存储在了一个FileList对象上,其中每个文件都对应了一个File对象,你可以通过这个FileList对象的length属性知道用户一共选择了多少个文件:
var numFiles = files.length;
可以通过普通的循环语句来操作每个单独的File对象:
for (var i = 0, numFiles = files.length; i < numFiles; i++) {
var file = files[i];
..
}
file对象有3个属性:
①name:文件名,只读字符串;
②size:文件大小,单位为字节
③type:MIME类型,只读字符串
4.在隐藏的文件输入框上调用click()方法
在上述写的预览代码中,隐藏<input>
的方法是设置opacity为0,绝对定位覆盖,但其实官方已有其他方法。
用display:none
隐藏,在需要的时候调用处它的click()方法,实现自定义界面打开文件选择对话框。
参考下列代码:
// html
// input的accept="image/*"表示可以接受任何格式的图片
<input type="file" id="fileElem" multiple accept="image/*" style="display:none" onchange="handleFiles(this.files)">
<a href="#" id="fileSelect">Select some files</a>