在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上傳其實還有不少小坑,未完待續......