学习文章:
HTML5 引入了一个 File API
用以提供用户上传文件的信息,并允许网页中的 JavaScript 访问其内容。
以下是一些表单 file
控件:
<input type="file" accept="video/*;capture=camcorder">
<input type="file" accept="audio/*;capture=microphone">
<input type="file" accept="image/*;capture=camera">直接调用相机(测试安卓可以,iphone还是有相册)
<input type="file" accept="image/*" />调用相机 图片或者相册
<input type="file" multiple accept="image/*" />调用相册
1 FileList
对象
FileList
对象针对表单的 file
控件。
当用户通过 file
控件选取文件后,这个控件的 files
属性值就是 FileList
对象。
// 多选控件
<input type='file' multiple />
<script>
document.querySelector('input').onchange = function() {
console.log(this.files);
};
</script>
控制台输出:
FileList {0: File, 1: File, length: 2}
0: File
1: File
length:2
__proto__: Object
除了用 file
控件,采用拖放方式,也可以得到 FileList
对象。
一般来说,我们不可能手动构造 FileList
对象,只能被动地读取,也就是说只有用户主动触发了文件读取行为,js 才能访问到 FileList
,而这通常发生在表单选择文件或者拖拽文件中。
2 File
对象
一个 FileList
对象包含我们选中的 File
对象,这个 File
对象含有以下属性值:
name
:文件名,该属性只读size
:文件大小,单位为字节,该属性只读type
:文件的 MIME 类型,如果分辨不出类型,则为空字符串,该属性只读lastModified
:文件的上次修改时间,格式为时间戳lastModifiedDate
:文件的上次修改时间,格式为 Date 对象实例
3 Blob
对象
File
对象是继承自 Blob
对象的,那 Blob
又是什么?
Blob
(Binary Large Object)对象代表了一段二进制数据,提供了一系列操作接口。其他操作二进制数据的 API(比如 File 对象),都是建立在 Blob
对象基础上的,继承了它的属性和方法。
生成 Blob
对象有两种方法:一种是使用 Blob
构造函数,另一种是对现有的 Blob
对象使用 slice
方法切出一部分。
4 FileReader
var reader = new FileReader();
FileReader
对象用于读取文件,即把文件内容读入内存。它的参数是 File
对象或 Blob
对象。
对于不同类型的文件,FileReader
提供不同的方法读取文件。
readAsText(Blob|File, opt_encoding)
:返回文本字符串。默认情况下,文本编码格式是 UTF-8,可以通过可选的格式参数,指定其他编码格式的文本readAsDataURL(Blob|File)
:返回一个基于Base64
编码的data-uri
对象(可用于<img>
标签中的src
属性,从而达到上传图片预览的效果)readAsArrayBuffer(Blob|File)
:返回一个ArrayBuffer
对象
FileReader
对象采用异步方式读取文件,可以为一系列事件指定回调函数。
onabort
方法:读取中断或调用 reader.abort() 方法时触发。onerror
方法:读取出错时触发。onload
方法:读取成功后触发。onloadend
方法:读取完成后触发,不管是否成功。触发顺序排在onload
或onerror
后面。onloadstart
方法:读取将要开始时触发。onprogress
方法:读取过程中周期性触发。(可以用来获取文件读取的进度)
5 createObjectURL
方法
// url 对象
var
URL = window.URL || window.webkitURL || window.mozURL,
SRC = URL.createObjectURL(file);
调用 URL
对象的 createObjectURL
方法,传入一个 File
对象或者 Blob
对象,能生成一个链接。这个 URL
可以放置于任何通常可以放置 URL
的地方,比如 <img>
标签的 src
属性。需要注意的是,即使是同样的二进制数据,每调用一次 URL.createObjectURL
方法,就会得到一个不一样的 URL
。
6 onprogress
事件
想要上传图片的时候显示进度条,就要使用上 HTML5 中的 onprogress
事件了。
onprogress
事件可以作用于 <video>
或 <audio>
标签中,作为其状态回调函数的作用。
也可以是作为 XMLHttpRequest
的指定事件,XMLHttpRequest
对象,传送数据的时候,有一个 progress
事件,用来返回进度信息。
它分成 上传和下载 两种情况:
- 下载的
progress
事件属于XMLHttpRequest
对象 - 上传的
progress
事件属于XMLHttpRequest.upload
对象
当上传或下载时,会频繁调用该方法。该方法接受一个事件参数 event
,其中 event.total
是需要传输的总字节,event.loaded
是已经传输的字节。如果event.lengthComputable
不为真,则 event.total
等于 0。
例子代码:
function uploadFile1(file,desc,catid){
var $process = $("#process_"+file.size);
var formData = new FormData(); //以下为像后台提交图片数据
formData .append('img_url', file);
formData .append('img_desc',desc);
formData .append('cat_id',catid);
var xhr=new XMLHttpRequest();
xhr.open('post','shop_gallery.php?act=update',true);
xhr.onreadystatechange=function (){
if(this.readyState==4){
$process.css("width","0%");
if (!(img_url.length == 0)) {
img_desc.splice(0, 1);
uploadFile1(img_url[0],img_desc[0],catid);
}
}
}
xhr.upload.onprogress=function (ev){
if(ev.lengthComputable){
var precent=100 * ev.loaded/ev.total;
$process.css("width",precent+'%');
if (precent == 100){
delimg1($process);
if (img_url.length == 0){
setTimeout("refresh("+catid+")", 1000 );
}
}
}
}
//
xhr.send(formData);
}