前言:該解決方案只支持IE10及以上,目前來(lái)看IE9及以下所占的份額越來(lái)越小了季惩,如果在項(xiàng)目不需要考慮IE9及以下的情況下录粱,使用HTML5是最好的方案。
HTML上傳文件的標(biāo)簽
<input type="file">
最基本的上傳文件標(biāo)簽
<input type="file" multiple="">
可以進(jìn)行多文件上傳的標(biāo)簽
<input type="file" accept=".jpg,.gif">
可以對(duì)上傳類型進(jìn)行限制的標(biāo)簽
使用accept屬性對(duì)上傳文件類型進(jìn)行限制很方便画拾,但是很容易被破解啥繁。如下圖:
使用accept進(jìn)行控制只允許上傳jpg后綴的文件:
<input type="file" accept=".jpg">
點(diǎn)擊上傳按鈕如下圖:
但是當(dāng)我們選擇右下角的文件類型為所有文件,如下圖:
所以目前看來(lái)使用accept屬性對(duì)上傳文件類型進(jìn)行限制基本上算是防君子不防小人了青抛。
JS對(duì)應(yīng)的事件和file控件DOM對(duì)象的接口
file控件上傳文件時(shí)觸發(fā)的事件是onchange
旗闽。
file控件DOM對(duì)象提供了多個(gè)文件操作API:
FileList對(duì)象表示用戶選擇的文件列表,在HTML4中file控件內(nèi)只允許放置一個(gè)文件,但在HTML5中通過(guò)添加multiple屬性适室,file控件內(nèi)允許放置多個(gè)文件嫡意。控件內(nèi)的每一個(gè)用戶選擇的文件都是一個(gè)file對(duì)象亭病,而FileList就是這些file對(duì)象的列表鹅很,代表用戶選擇的所有文件。
調(diào)用方法:假設(shè)file控件DOM對(duì)象名為file罪帖,則調(diào)用方法為file.files
。file對(duì)象有兩個(gè)屬性邮屁,一個(gè)是name整袁,代表文件名不包含文件的路徑;一個(gè)是lastModifiedDate佑吝,表示文件最后被修改的日期坐昙。
調(diào)用方法:假設(shè)file控件DOM對(duì)象名為file,則第一個(gè)用戶選擇文件的調(diào)用方法為file.files[0]
芋忿。HTML5中Blob表示二進(jìn)制原始數(shù)據(jù)炸客,它提供一個(gè)slice()方法,可以通過(guò)這個(gè)方法訪問(wèn)到字節(jié)內(nèi)部的原始數(shù)據(jù)塊戈钢。事實(shí)上痹仙,上面提到的file對(duì)象繼承了Blob對(duì)象。Blob對(duì)象的兩個(gè)屬性殉了,
size:表示一個(gè)對(duì)象的字節(jié)長(zhǎng)度开仰。
type:表示一個(gè)對(duì)象的MIME類型,如若是未知類型返回空字符串薪铜。
調(diào)用方法:沒(méi)有調(diào)用方法众弓,只是file控件DOM對(duì)象的file對(duì)象繼承了Blob對(duì)象。
FileReader接口
四個(gè)方法:
方法名 | 參數(shù) | 描述 |
---|---|---|
readAsBinaryString() | file | 將文件讀取為二進(jìn)制字符串隔箍,通常將它傳到后端谓娃,后端可以通過(guò)這段字符串存儲(chǔ)文件 |
readAsDataURL() | file | 將文件讀取為一段data url字符串,事實(shí)上是將小文件以一種特格式的URL地址直接讀取到頁(yè)面蜒滩。小文件通常指圖片與html等格式文件 |
readAsText() | file [encoding] | 將文件以文本的方式讀取滨达,其中第二個(gè)參數(shù)為文本的編碼 |
abort() | (none) | 中斷讀取操作 |
監(jiān)聽(tīng)事件:
事件 | 描述 |
---|---|
onabort | 數(shù)據(jù)讀取中斷時(shí)發(fā)生 |
onerror | 數(shù)據(jù)讀取出錯(cuò)時(shí)發(fā)生 |
onloadstart | 數(shù)據(jù)讀取開(kāi)始時(shí)發(fā)生 |
onload | 數(shù)據(jù)讀取成功完成時(shí)發(fā)生 |
onloadend | 數(shù)據(jù)讀取完成時(shí)發(fā)生無(wú)論讀取成功還是失敗 |
onprogess | 數(shù)據(jù)讀取中 |
一個(gè)簡(jiǎn)單的例子:
只實(shí)現(xiàn)了IE10以上的圖片上傳預(yù)覽,已經(jīng)獲取文件類型帮掉,大小和寬高弦悉,并且打印了日志,但是沒(méi)有阻止上傳蟆炊。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<form action="">
<div><img src="" alt=""></div>
<input type="file" multiple="">
</form>
<script>
var img1 = document.querySelector('img');
var div = document.querySelector('div');
var input = document.querySelector('input');
input.onchange = function () {
if (input.files && input.files[0]) {
if(input.files[0].type == "image/jpeg" || input.files[0].type == "image/gif" || input.files[0].type == "image/png"){
var byteSize = input.files[0].size / 1024;
if(byteSize <= 250){
var reader = new FileReader();
reader.readAsDataURL(input.files[0]);
reader.onload = function(ev){
var txt = ev.target.result;
var img = new Image();
img.src = txt;
img.onload = function(){
if(img.width <= 500 && img.height <= 500){
console.log("圖片沒(méi)有錯(cuò)");
img1.src = txt;
}else{
console.log("尺寸不對(duì) " + img.width + "*" + img.height);
}
}
}
}else{
console.log("文件大小超出 " + byteSize);
}
}else{
console.log("文件類型不對(duì) " + input.files[0].type);
}
}else{
console.log("沒(méi)有上傳稽莉,使用默認(rèn)");
}
}
</script>
</body>
</html>
參考:
- http://blog.csdn.net/testcs_dn/article/details/8695532
- http://blog.csdn.net/oscar999/article/details/37499743/
- http://blog.csdn.net/hdchangchang/article/details/9036511
下一步目標(biāo):實(shí)現(xiàn)拖拽上傳