
文件API
引言
在之前我们操作本地文件都是使用flash或者第三方的activeX插件等技术,由于使用了这些技术后就很难进行跨平台、或者跨浏览器、跨设备等情况下实现统一的表现,从另外一个角度来说就是让我们的web应用依赖了第三方的插件,而不是很独立。在HTML5标准中,默认提供了操作文件的API(应用程序编程接口)让这一切直接标准化。有了操作文件的API,让我们的Web应用可以很轻松的通过JS来控制文件的读取、写入、文件夹、文件等一系列的操作!
JS对象
FileList对象与File对象
它是File对象的一个集合,在Html4标准中文件上传控件只接受一个文件,而在新标准中,只需要设置multiple,就支持多文件上传,所以从此标签中获取的files属性就是FileList对象实例。
H5在DOM中为文件输入元素添加了一个files集合,在通过文本输入字段选择了一或多个文件时,files集合中将包含一组File对象,每个File对象对应着一个文件。每个File对象都有下列只读属性。
name: 本地文件系统的文件名
size:文件的字节大小
type:字符串,文件的MIME类型。
lastModifiedDate:字符串,文件上一次被修改的事件
<script language=javascript>
function ShowFileName(){
var file;
//document.getElementById("file").files返回FileList文件列表对象
for(var i=0;i<document.getElementById("file").files.length;i++){
//file对象为用户选择的单个文件
file = document.getElementById("file").files[i];
//此处您可以针对FileList文件列表中每个文件进行多种处理,本例中只弹出文件名
alert(file.name);
}
}
</script>
选择文件:
<input type="file" id="file" multiple size="80"/>
<input type="button" onclick="ShowFileName();" value="文件上传"/>
运行结果如下图:

2.Blob对象
Blob表示二进制原始数据,它提供一个slice方法,可以通过该方法访问到字节内部的原始数据块。事实上,上面提到的file对象也继承了这个Blob对象。
Blob对象有两个属性,size属性表示一个Blob对象的字节长度。type属性表示Blob的MIME类型,如果是未知类型,则返回一个空字符串。
function ShowFileType(){
var file;
//得到用户选择的第一个文件
file = document.getElementById("file").files[0];
var size=document.getElementById("size");
//显示文件字节长度
size.innerHTML=file.size;
var type=document.getElementById("type");
//显示文件类型
type.innerHTML=file.type;
}
</script>
选择文件:
<input type="file" id="file" />
<input type="button" value="显示文件信息" onclick="ShowFileType();"/><br/>
文件字节长度:<span id="size"></span><br/>
文件类型:<span id="type"></span>

对于图像类型的文件,Blob对象的type属性都是以image/开头的,后跟图像类型,利用此特性我们可以在JS中判断用户选择的文件是否为图像文件,如果在批量上传时,只允许上传图像文件,可以利用该属性,如果用户选择的多个文件中有不是图像的文件时,可以弹出错误提示信息,并停止后面的文件上传,或者跳过这个文件,不将该文件上传。
function FileUpload(){
var file;
for(var i=0;i<document.getElementById("file").files.length;i++){
file = document.getElementById("file").files[i];
if(!/image\/\w+/.test(file.type)){
alert(file.name+"不是图像文件!");
break;
}
else{
//此处可加入文件上传的代码
alert(file.name+"文件已上传");
}
}
}
</script>
选择文件:
<input type="file" id="file" multiple/>
<input type="button" value="文件上传" onclick="FileUpload();"/>
运行结果:


另外,H5中已经对file控件添加了accept属性,企图让file控件只能接受某种类型的文件,但是目前各主流浏览器对其的支持都只限于在打开文件选择窗口时,默认选择图像文件而己,如果选择其他类型文件,file控件也能正常接受。
<input type="file" id="file" accept="image/*" />
运行结果:

FileReader接口
FileReader接口主要用来把文件读入内存,并且读取文件中的数据。FileReader接口提供 了一个异步API ,使用该API可以在浏览器主线程中异步访问文件系统,读取文件中的数据。
//检测浏览器是否支持FileReader接口
if(typeof FileReader=='undefined'){
alert("浏览器不支持FileReader接口")
}else{
var reader=new FileReader();
}
FileReader接口的方法
FileReader接口拥有4个方法,其中3个用以读取文件,另一个用来将读取过程中断。无论读取成功或失败,并不会返回读取结果,这一结果存储在result属性中。

FileReader接口的事件
FileReader接口还包含了一套完整的事件模型,用于捕获读取文件时的状态。

FileReader接口的使用示例
<script language=javascript>
var result=document.getElementById("result");
var file=document.getElementById("file");
if (typeof FileReader == 'undefined' ){
result.innerHTML = "<p>抱歉,你的浏览器不支持 FileReader</p>";
file.setAttribute( 'disabled','disabled' );
}
//将文件以Data URL形式进行读入页面
function readAsDataURL(){
//检查是否为图像文件
var file = document.getElementById("file").files[0];
if(!/image\/\w+/.test(file.type)){
alert("请确保文件为图像类型");
return false;
}
var reader = new FileReader();
//将文件以Data URL形式进行读入页面
reader.readAsDataURL(file);
reader.onload = function(e){
var result=document.getElementById("result");
//在页面上显示文件
result.innerHTML = ''
}
}
//将文件以二进制形式进行读入页面
function readAsBinaryString(){
var file = document.getElementById("file").files[0];
var reader = new FileReader();
//将文件以二进制形式进行读入页面
reader.readAsBinaryString(file);
reader.onload = function(f){
var result=document.getElementById("result");
//在页面上显示二进制数据
result.innerHTML=this.result;
}
}
//将文件以文本形式进行读入页面
function readAsText(){
var file = document.getElementById("file").files[0];
var reader = new FileReader();
//将文件以文本形式进行读入页面
reader.readAsText(file);
reader.onload = function(f){
var result=document.getElementById("result");
//在页面上显示读入文本
result.innerHTML=this.result;
}
}
</script>
<p>
<label>请选择一个文件:</label>
<input type="file" id="file" />
<input type="button" value="读取图像" onclick="readAsDataURL()"/>
<input type="button" value="读取二进制数据" onclick="readAsBinaryString()"/>
<input type="button" value="读取文本文件" onclick="readAsText()"/>
</p>
<div name="result" id="result">
<!-- 这里用来显示读取结果 -->
</div>
在这个示例中,选取不同类型的文件,然后点击不同的按钮,浏览器会读取这些文件的各种数据,然后显示在画面中。当然您也可以选择不显示 ,而是直接提交到后端,然后保存到文件中或输送到数据库中。代码中fileReader对象读取到的数据都保存在了result属性中。
<script language=javascript>
var result=document.getElementById("result");
var input=document.getElementById("input");
if(typeof FileReader=='undefined'){
result.innerHTML = "<p class='warn'>抱歉,你的浏览器不支持 FileReader</p>";
input.setAttribute( 'disabled','disabled' );
}
function readFile(){
var file = document.getElementById("file").files[0];
var reader = new FileReader();
reader.onload = function(e){
result.innerHTML = ''
alert("load");
}
reader.onprogress = function(e){
alert("progress");
}
reader.onabort = function(e){
alert("abort");
}
reader.onerror = function(e){
alert("error");
}
reader.onloadstart = function(e){
alert("loadstart");
}
reader.onloadend = function(e){
alert("loadend");
}
reader.readAsDataURL(file);
}
</script>
<p>
<label>请选择一个图像文件:</label>
<input type="file" id="file" />
<input type="button" value="显示图像" onclick="readFile()" />
</p>
<div name="result" id="result">
<!-- 这里用来显示读取结果 -->
</div>
在这个示例中,我们通过点击显示图像按钮在画面中读入一个图像文件,通过这个过程我们可以了解按顺序触发了哪些事件,并用提示信息的形式报出这些事件的名字。我们需要编写的代码主要都是在onprogress事件中,譬如可以用H5中的新增元素progress来显示大文件的读取完成百分比。
拖放API
属性
draggable 设置为true 可以被拖拽
img和a元素默认可拖,其他元素默认不可拖,加一个draggable=true让它可拖。
<div draggable='true'></div>
拖拽事件
源对象:
ondragstart 开始被拖动的时候触发 绑定给被拖动的元素
ondrag 拖动的过程总被连续触发 绑定给被拖动的元素
ondragend 停止拖动的时候的触发 绑定给被拖动的元素
过程对象:
ondragenter 当被拖拽的元素进入到目标元素 绑定给目标元素 用于进入目标去区域时 目标区域样式改变
ondrageover 当被拖拽的元素在目标元素内移动 绑定给目标元素 需要组织默认的动作 event.preventDefault()
ondrageleave 当被拖拽的元素离开目标元素 绑定给目标元素
目标对象:
ondrop 在目标元素内停止拖拽 绑定给目标元素
总结
HTML5的文件API和拖放api非常简洁实用,为我们省去了很多麻烦。
喜欢可关注公众号“十斤代码”

回复“领取前端电子书”可免费领取知识哦~~
