分类: HTML5
2013-10-24 09:56:29
说明:
本文阐述了如何用和JavaScript上传文件。HTML5提供输入类型“文件”允许我们与本地文件互动,文件输入类型对于从用户那提走一些示例并进行一些操作来说可能非常有用。我们将在项目中用File API,因此如果你需要任意功能的任何细节描述,都可以查看API。它还包含各种其它处理二进制文件的方式。我们将使用FileList界面来获取文件清单。用File Reader界面来读取文件,用File界面来获取文件属性等。
检查支持
因为HTML5还比较新,并非其所有功能都被浏览器支持,所以你最好是检查一下你的浏览器支持文件特性如何。要检查这个,只需将下面的代码放入你的HTML文件并看看是否得到警告。
如果你得到如下信息,你就可以跟随讲解继续;否则,你需要升级浏览器。
文件输入标签
文件输入标签跟其他HTML的输入标签一样,唯一的区别是“类型”。对于文件类型输入,我们需要设置元素类型为“file”类,如下所示:
选择文件
要选择一个文件,只需点击你的HTML页面上的“Choose file(选择文件)”按钮并从对话框中选择一个文件。如果你已经启用多个选择,你可以选择多个文件。请参考下图:
处理选择的文件
现在我们已经有了选中的文件,下一步我们将检查文件属性,因此我们将使用File界面。File界面有两个很重要的属性,会对我们很有帮助。它们分别是:
readonly attribute DOMString name;
readonly attribute Date lastModifiedDate;
作为attributesindicate的名称,前一个提供文件名,后一个提供最后修改时间。
要在JavaScript中使用这个界面(从现在开始我们只用脚本),只需如下代码:
function startRead(evt) { var file = document.getElementById(‘file‘).files[0]; if (file) { // getAsText(file); alert("Name: " + file.name + "\n" + "Last Modified Date :" + file.lastModifiedDate); } }
现在在你的HTML输入标签中,添加一个onchange事件并按如下方法调用该功能:
<input type=file id=’file’ onchange="startRead()"/>
如果你到现在为止一切正确,你会得到一个类似于下图的输出。
添加拖放
到现在,我们通过使用按钮选择文件,但为精益求精,我们可以添加一个拖放支持,从而用户可以拖拽文件来打开它,要实现这个功能需要添加如下脚本到你的脚本中:
function startReadFromDrag(evt) { var file = evt.dataTransfer.files[0]; if (file) { // getAsText(file); var fileAttr = "Name: " + file.name + "\n" + "Last Modified Date :" + file.lastModifiedDate; $(‘#draghere’).text(fileAttr); alert(fileAttr); } evt.stopPropagation(); evt.preventDefault(); } var dropingDiv = document.getElementById(‘draghere‘); dropingDiv.addEventListener(‘dragover‘, domagic, false); dropingDiv.addEventListener(‘drop‘, startReadFromDrag, false);
为了更好的输出,也添加到HTML和类型代码中。
<div id="draghere" >Drop files herediv> #draghere{ width:300px; height:100px; background-color:rgba(221,214,155,0.4); border:1px dashed black; text-align:center; }
读取文件内容
现在的主要部分是读取文件内容。我们将使用File Reader界面。它为我们提供如下方式来处理文本和二进制文件:
void readAsArrayBuffer(Blob blob); void readAsText(Blob blob, optional DOMString encoding); void readAsDataURL(Blob blob);
第三种方式是在数据URL形式中读取文件内容时使用的,第二种方式是在读取基于文本的文件(支持编码诸如UTF-8和UTF-16)时使用,第一种方式用于将数据当作阵列对象读取。
我们将选择第二种和第三种方式。
要读取文件需添加如下脚本、HTML和类型到你的文件中。
<div id="op">div> Style #op{ width:300px; height:300px; overflow:auto; background-color:rgba(221,214,221,0.3); border:1px dashed black; } Script function getAsText(readFile) { var reader = new FileReader(); reader.readAsText(readFile, "UTF-8″); reader.onload = loaded; } function loaded(evt) { alert("File Loaded Successfully"); var fileString = evt.target.result; $("#op").text(fileString); }
我们所做的是添加div(有一个ID输出)到我们将要显示文件文本的地方。在脚本中,getAsText(readfile)主要地创建了新的FileReader对象来读取文件。然后在下一行,我们用readAsText()来从文件中获取文本。这是一个异步函数,所以我们需要在使用文本前等待它完成。我们添加onload事件到读取器对象从而让我们在读取一完成时就能得到通告。读取完成会调用已加载的函数。在其中我们简单地显示op div内函数的文本。如果你到现在一切无误,那么你就完成了。检查下列输出。哦,不好意思我忘了提醒你要从所有读取函数中取消备注getTextFile()的调用。
现在读取一个图像文件只需要用下列代码替换你的上述函数:
function startRead(evt) { var file = document.getElementById(‘file‘).files[0]; if (file) { if (file.type.match("image.*")) { getAsImage(file); alert("Name: " + file.name + "\n" + "Last Modified Date :" + file.lastModifiedDate); } else { getAsText(file); alert("Name: " + file.name + "\n" + "Last Modified Date :" + file.lastModifiedDate); } } evt.stopPropagation(); evt.preventDefault(); } function startReadFromDrag(evt) { var file = evt.dataTransfer.files[0]; if (file) { if (file.type.match("image.*")) { getAsImage(file); alert("Name: " + file.name + "\n" + "Last Modified Date :" + file.lastModifiedDate); } else { getAsText(file); alert("Name: " + file.name + "\n" + "Last Modified Date :" + file.lastModifiedDate); } } evt.stopPropagation(); evt.preventDefault(); } function getAsImage(readFile) { var reader = new FileReader(); reader.readAsDataURL(readFile); reader.onload = addImg; } function addImg(imgsrc) { var img = document.createElement(‘img‘); img.setAttribute("src", imgsrc.target.result); document.getElementById("op").insertBefore(img); }
该代码并非像咋一看那样大。它主要包含用之前的方法做了细微改动的样板式代码。getAsImage()方式主要将图像读取为一个数据URL然后将其发送到“addImg()”。它们创建了一个新的图像元素并附之于op div上。“File.type.match”用来识别文件类型。检查下图中的输出。