本篇文章的主要目的是介绍本地文件相关 API
的使用,好的,废话不多说,下面直接开始。
基础的 File API
File Api
提供了在浏览器中与本地文件进行交互的最基础的方法,不过值得注意的是,由于安全问题,开发者并不能主动的去访问客户端的文件信息,也就是说这一过程需要用户的参与,最常用的获取本地文件的手段莫过于两种:
- 用户通过
input[type = file]
控件选择了本地某个文件。 - 用于通过拖拽将本地的某一文件拖到浏览器完成上传。
通过上面两种形式,我们都可以获取到可以操作的 File
接口,不过还有一点值得注意的是,无论是通过利用控件的形式还是通过拖拽的形式,用户都可以同时选中多个文件,而当用户选择多个文件的时候我们获取到的其实是 FileList
接口,顾名思义,它就是一个 File
接口的集合。
那么,通过 File
接口我们能够获取到哪些信息呢?
-
name
: 文件名 -
type
:ASCII
编码,MIME
格式的文件类型。 -
size
: 文件所占的字节 (byte
)。 -
lastModifiedDate
: 文件最后修改的日期和时间。
注: File API
不能遍历文件目录。
通过上面介绍的这些内容,我们就可以很轻易的写出一个小 demo
,就像下面的这样。
其实现过程就是利用 input[type=file]
控件选择多个文件,不过在这里我们并没有直接使用这个控件,而是利用 button
来触发这个控件的功能。然后通过用户选择的文件会返回一个 FileList
对象,通过对其包含的每个 File
进行属性的读取即可。其核心代码如下:
uploadButton.addEventListener("click", function() {
fileInput.click();
}, false);
fileInput.addEventListener("change", function() {
if (fileInput.files) {
var length = fileInput.files.length;
for(var i = 0; i < length; i++) {
fileList.appendChild(getFileDetailDIV(fileInput.files[i]));
}
}
}, false);
这个时候这个小 demo
还不够人性化,毕竟有的人他就是不喜欢利用控件上传文件,他就是喜欢利用拖放将文件传上来,那么为了这部分用户,我们就得多费点脑筋了,怎么才能利用拖放获取到一个文件的信息呢?
在这之前,我想插入一些拖放的知识。因为网页中并不是每一种元素都可以成为放置目标,所以如果想自定义放置目标,那么我们需要修改 dragover
和 dragenter
的默认行为,代码如下:
var droptarget = document.getElementById("custom-target");
droptarget.addEventListener("dragenter", function(e) {
e.preventDefault();
}, false);
droptarget.addEventListener("dragover", function(e) {
e.preventDefault();
}, false);
还有一点值得注意的是,当你将目标拖拽到地点以后,鼠标松开的时候就会触发 drop
事件,不过放置事件也是有默认行为的,比如当拖拽的目标是图片的时候,页面就会转向图片,当拖拽的目标是音乐或者视屏的时候,页面就会按照默认的方式打开这些文件,所以如果不想这些事情发生,我们需要阻止 drop
事件的默认行为。
最后一点,当我们拖拽文件的时候,通过 dataTransfer,files
就可以获得选中的文件,而且其返回的结果是 FileList
接口。下面就让我们以拖拽的形式完成上面的功能。
其核心代码如下所示:
dragtarget.addEventListener("dragenter", function(e) {
e.preventDefault();
}, false);
dragtarget.addEventListener("dragover", function(e) {
e.preventDefault();
}, false);
dragtarget.addEventListener("drop", function(e) {
e.preventDefault();
var files = e.dataTransfer.files,
length = files.length;
for(var i = 0; i < length; i++) {
fileList.appendChild(getFileDetailDIV(files[i]));
}
}, false);
File Reader
上面已经介绍了 File API
的使用,不过仅仅是能够获取到文件的属性,实用价值非常有限,所以在 HTML5 File API
中提供了一个新的接口 FileReader
,该接口为开发者提供了从客户端 JS
异步读取文件的方法,属性和事件,下面就先来看看它提供的四种不同的读取方法。
-
readAsArrayBuffer( Blob )
: 以ArrayBuffer
格式返回文件内容。 -
readAsBinaryString( Blob )
: 以二进制字符串的形式返回文件内容。 -
readAsText( Blob, [, encoding] )
: 以DOMString
文本返回文件内容。 -
readAsDataURL( Blob )
: 以数据URL DOMString
返回文件内容。
事件如下:
-
loadstart
: 文件读取操作开始时触发。 -
progress
: 浏览器读取文件过程中触发。 -
abort
: 执行放弃操作时触发。 -
error
: 文件读取过程中出现错误时触发。 -
load
: 文件成功读取后触发。 -
loadend
文件读取完成后(无论成功或者失败)触发。
既然已经知道了这么多的事件和方法,那么我们就的知道当读取完成后,我们需要的信息存放在何处?
通过上面的介绍,我们已经知道当文件读取成功后,会触发 load
事件,我们想要的事件就在 load
事件中的 event.target.result
中。下面我们针对各个方法做实验,首先创建一个文本 test.txt
,其内容如下:
You can import usage data from your Google Analytics account and see exactly how well a feature is supported among your own site's visitors. Look under the Settings panel to get started!
关于 readAsArrayBuffer()
和 readAsBinaryString()
这两个方法在此就不演示了,因为我个人对 ArrayBuffer
的应用场景还不是很清楚,所以下面直接利用 readAsText()
和 readAsDataURL()
这两个方法。
利用 readAsText()
的代码如下:
var fileReader = new FileReader();
fileReader.addEventListener("load", function(e) {
console.log(e.target.result);
}, false);
fileReader.readAsDataURL(file);
其返回的结果如下所示:
可见,它只是将你选择的文本读取出来了,其实通过方法的名字你可能也已经猜出大概了。这有什么用呢?很明显,我们可以利用这个方法编写一个在线阅读或者修改的小应用。
还有一个方法是 readAsDataURL()
, 这个方法的返回值如下:
可见,这个方法只是返回一个 URL
地址,而通过这个地址我们就可以获取到选中的文件,这个方法非常的有用,比如你想开发图片预览相关的功能或者是在线播放本地音频的应用,都可以利用该方法获取到一个连接到本地资源的 URL
,然后进行操作。在以前,要完成同样的功能,必须要将相应的图片或者资源上传到服务器才可以使用。
好了,先写到这里,如果日后用到与文件操作相关的属性,还会更新本文章!