在h5出来以前,图片预览对于前端来讲是很是有局限性的,须要配合后端实现,经过后端拿到地址后显示,h5出来后,图片预览变为可能,h5提供了新的file上传api-URL和FileReader。javascript
先来讲下FileList,FileReader和URL的预览都须要先获取到FileList对象(类数组),file类型表单在上传文件时,经过javascript获取到该表单的files,files就是FileList对象,FileList对象获取计算机上文件的存储信息与数据。css
files简单代码以下html
file.addEventListener('change',function(e){
var files = this.files||e.target.files;
console.log(files);
});
复制代码
files在console.log打印以下,里面包含了图片最后更改时间,图片大小类型等等; 前端
URL是window下的一个对象,URL.createObjectURL是一个静态方法,经过FileList对象数据建立一个url地址(相似于http格式),个人理解是至关于一个地址的引用,性能相对FileReader来讲要好一点,并且不会丢失参数,优先选择的预览方式。html5
FileReader是一个构造函数,经过实例化一个对象能够读取FileList对象数据并转换为base64,base64格式为data:......,base64在一些奇奇怪怪的手机可能会丢失掉文件格式参数致使显示不出来,转换为base64格式体积增长1/3,体积太大的图片会使页面cpu上升,建议经过服务器转成一个url地址。base64在预览而且要canvas剪辑的时候用得多一点。java
下面经过一个简单的例子来讲明,上代码直接撸起来web
htmlcanvas
<!--上传容器-->
<div class="upload">
<input type="file" class="file" multiple="multiple"
accept="image/jpeg,image/png,image/gif"/>
</div>
<!--图片容器-->
<div class="content">
</div>
复制代码
上传文件的两种选择方式后端
var file = document.querySelector('.file'),//上传input
content = document.querySelector('.content'),//盛放图片容器
select,//上传方式
filter = {
"jpeg": "/9j/4",
"png": "iVBORw",
"gif": "R0lGOD"
}; //验证格式,base64包含图片格式的,
但在个别奇葩手机图片格式丢失
file.addEventListener('change',function(e){
var files = this.files||e.target.files;
console.log(files)
if(files){//支持html5的api
if(window.URL||window.webkitURL||window.mozURL){
select.src(files);//方式一,优先选择
}else if(window.FileReader){
select.base64(files);//方式二
}
}
});
复制代码
两种方式的实现,经过闭包只暴露方法不暴露私有变量,按照策略模式,把实现代码和逻辑代码分离开,经过add增长方法。策略模式听起来可能有点难理解,但看代码应该就明白了。api
select=(function(){
var way ={
src:url,//方式一
base64:base64,//方式二
add:function(key,callback){
this[key]=callback;
}//增长上传预览方法
};
//方式一
function url(files){
for(var a=0,f=files.length;a<f;a++){
var url = window.URL || window.webkitURL || window.mozURL;
var src = url.createObjectURL(files[a]);
preview(src);//预览图片
}
};
//方式二
function base64(files){
for(var a=0,f=files.length;a<f;a++){
var obj = new FileReader();
obj.readAsDataURL(files[a]);
obj.onload=function(e){
console.log(validate(e.target.result))
if(!validate(e.target.result)){
alert('格式错误');
return;
}
preview(e.target.result);//预览图片
}
}
};
return way;
})();
复制代码
这部分只是把复用的代码封装成为那个函数调用分别是验证图片格式和预览图片
//验证格式
function validate(data){
for(var item in filter){
if(data.indexOf(filter[item])>-1){
return true;
}
}
return null
}
//预览图片
function preview(src){
var img = document.createElement('img');
img.src=src;
img.style.cssText="max-width:100px;"
content.appendChild(img);
}
复制代码
h5新的api使得纯前端也能实现图片预览功能,以上只是简单的分析,关于h5上传其实还有不少小坑,未完待续......