程序中,首先判断当前浏览器中文件API是否可用,如果可用的话则调用init的初始方法。在init方法中,做了如下几件事情:
为文件的选择框增加了上传的监听事件。
显示#filedrag区域
- 设置了拖动文件经过放置区域时和文件离开放置区域时的事件以及样式。
- 设置了当用户将文件拖动到放置区域最后松开鼠标,以决定文件放置时的事件。
- 这里还隐藏了提交按钮,因为这里并不需要它了。
当然,这里还可以连传统的文件上传浏览框也去掉,但这并不是十分友好,所以这里采用的是两者并存的方式。
而用到了XMLHttpRequest的upload方法,主要是防止在一些浏览器中如果当文件上传API不可用时,则用旧的方法,不显示文件拖拉框,取而代之的是显示传统的上传提交按钮。
考虑到很少用户很熟悉文件的这种拖拉上传用法,因此,我们在事件中对文件放置区域的样式进行设置,当文件被拖拉到区域中时,区域的边框会变成红色,以提醒用户,代码如下:
e.stopPropagation();
e.preventDefault();
e.target.className = (e.type == "dragover" ? "hover" : "");
}
这里判断是否文件拖拉到区域上方,如果是的话,则采用样式中的hover样式(见上文)。
接下来,我们会在另外的一个div区域中,显示文件上传的小结信息,代码如下:
FileDragHover(e);
// 获得所有的文件列表
var files = e.target.files || e.dataTransfer.files;
// 循环处理每个文件
for (var i = 0, f; f = files[i]; i++) {
ParseFile(f);
}
}
在FileSelectHandler事件中,实现了如下的功能:
1 调用FileDragHover()方法移除了hover的样式,并且取消浏览器的响应事件,否则的话浏览器会尝试显示文件的内容。
2 将上传的文件放置到FileList对象数组中去,包括用传统文件上传框上传的及用拖拉方法上传的。
3 单独使用一个方法ParseFile输出上传每个文件的具体属性信息,代码如下;
Output(
"
File information: " + file.name +
" type: " + file.type +
" size: " + file.size +
" bytes
"
);
}
使用Javascript打开客户端文件
现在,我们已经把客户端机器上的文件成功拖拉到浏览器中了,也就是说,我们用新的拖拉的方法,完成了以往要使用传统的文件上传选择框才能完成的工作!接下来,我们尝试通过Javascript,去判断用户上传的文件类型,并学习如何使用Javascript去操作客户端的文件。
首先,为什么要通过Javascript去分析操作客户端的文件呢?假如要求用户上传很多文件,或者上传指定格式的图片,假如用户选好上传文件到服务端后,服务端才判断发现文件不符合要求,再要求用户重新上传的话,给用户的体验则不大友好,所以,希望能在用户在客户端选择完文件后就马上能判断出文件的大小和类型,如果是图片的话,甚至可以实现客户端图片预览的效果。
在HTML5的起草标准中,提供了FileReader接口去处理客户端的文件,有如下几个重要API:
readAsText(File f, [encoding]):将一个文件读入到字符串中去,其中可以选用文件的编码,默认的是UTF-8
.readAsDataURL(File f): 将文件以data URL编码的方式读入文件内容,dat Url方式是一种以BASE64编码在页面中展示文件的方法,详细见:http://en.wikipedia.org/wiki/Data_URI_scheme
.readAsBinaryString(File f): 将文件以二进制方式读取。.readAsArrayBuffer(File f):.将文件作为ArrayBuffer对象的方式读取。ArrayBuffer详见http://www.khronos.org/registry/typedarray/specs/latest/
接下来,我们看下如何在Javascript中异步打开读取文件。
Javascript中异步打开文件
先来复习下之前我们用到的parseFile方法,代码如下:
Output(
"
File information: " + file.name +
" type: " + file.type +
" size: " + file.size +
" bytes
"
);
}
这里只是简单显示了文件的文件名和文件大小,而接下来我们要判断是这个文件是否属于文件类型的文件(即text/plain,text/html,text/css等),可以使用FileReader.readAsText()方法读取并且去掉其中的<,>符号,代码如下;
var reader = new FileReader();
reader.onload = function(e) {
Output(
"
" + file.name + ":
" +
e.target.result.replace(//g, ">") +
"
"
);
}
reader.readAsText(file);
}
同样,我们希望将一张图片从用户的资源管理器中,拖拉到页面的放置区域后,能马上显示这张图片的实际内容以及大小,可以用如下代码实现:
0.if (file.type.indexOf("image") == 0) {
0. var reader = new FileReader();
0. reader.onload = function(e) {
0. Output(
0. "<p><strong>" + file.name + ":</strong><br />" +
0. '<img src="' + e.target.result + '" /></p>'
0. );
0. }
0. reader.readAsDataURL(file);
0.}
这里,直接将图片的内容以FileReader的readAsDataURL方法读取入并显示。
最后,我们可以通过http://blogs.sitepointstatic.com/examples/tech/filedrag/2/index.html观看我们的
DEMO演示,请读者尝试从自己电脑上的windows资源管理器中,拖放图片或其他类型文
件到页面的指定区域中,则会发现浏览器能自动识别用户拖放的文件,当然,请使用Chrome
或Firefox浏览器才能看到效果。
小结
在本文中,为读者介绍了HTML5中新的文件处理API,利用文件处理API,可以实现让浏览器识别从用户端拖放到页面的文件,在下一讲中,将重点介绍如何上传这些已经拖放了的文件。