HTML5拖放文件上传详解:客户端文件处理与异步服务器上传
核心要点
将桌面文件拖放到浏览器中是Web应用程序集成的最终目标之一。这是由四部分组成的系列文章的第一部分,介绍如何:1. 启用将文件拖放到网页元素上;2. 在JavaScript中分析已拖放的文件;3. 在客户端加载和解析文件;4. 使用XMLHttpRequest2异步将文件上传到服务器;5. 在上传过程中显示图形进度条;6. 使用渐进增强确保文件上传表单在任何浏览器中都能工作(对于所有IE6粉丝来说都是好消息!);7. 使用纯JavaScript代码而无需库。
浏览器兼容性挑战
在开始之前,本教程涉及一些最新的HTML5技术,因此预计支持情况会参差不齐。代码现在可以工作,但API可能会发生变化,浏览器也会不断发展。- 最新版本的Firefox和Chrome支持所有功能,并且运行完美。- Opera可以在JavaScript中解析文件,但未实现文件拖放和XMLHttpRequest2上传。- IE和Safari的桌面版不支持任何API。- Apple已在Safari的iPhone和iPad版本上禁用了HTML文件上传表单。有人知道为什么吗?
最后,请注意,我的代码显示了基本概念。错误检查很少,您需要针对生产系统进行调整。
HTML和CSS
这是一个带有文件输入类型的标准表单。唯一的HTML5功能是“multiple”属性,它允许用户选择任意数量的文件。我们将文件上传到运行PHP的服务器,但无论您使用什么技术,代码都差不多。隐藏的MAX_FILE_SIZE值指定300,000字节——PHP使用此值,但我们也会在客户端检查它以防止上传大型文件。
<fieldset><legend>HTML文件上传</legend> <div> <input type="file" id="fileselect" name="fileselect[]" multiple="multiple"> <label for="fileselect">选择要上传的文件:</label> <div id="filedrag">或将文件拖放到此处</div> </div> <input type="submit" value="上传文件" id="submitbutton"> </fieldset> <div id="messages">状态信息</div>
#filedrag { display: none; font-weight: bold; text-align: center; padding: 1em 0; margin: 1em 0; color: #555; border: 2px dashed #555; border-radius: 7px; cursor: default; } #filedrag.hover { color: #f00; border-color: #f00; border-style: solid; box-shadow: inset 0 3px 4px #888; }
我们还定义了一个.hover类,当用户将文件拖到元素上时,该类会更改样式。浏览器在这种情况下不会应用:hover样式,但是当事件发生时,我们可以使用JavaScript添加类。
文件API
W3C文件API提供了一些对象。我们将使用:- FileList:表示所选文件的数组。- File:表示单个文件。- FileReader:一个接口,允许我们在客户端读取文件数据并在JavaScript中使用它。
附加JavaScript事件
是时候开始使用一些JavaScript了。我们没有使用JavaScript库,因此,为了节省我们的打字手指,我们将创建几个辅助函数来通过ID返回元素并输出状态消息:
// 通过ID获取元素 function $id(id) { return document.getElementById(id); } // 输出信息 function Output(msg) { var m = $id("messages"); m.innerHTML = msg + m.innerHTML; }
我们现在将检查File API是否可用并调用Init()函数:
// 调用初始化文件 if (window.File && window.FileList && window.FileReader) { Init(); } // 初始化 function Init() { var fileselect = $id("fileselect"), filedrag = $id("filedrag"), submitbutton = $id("submitbutton"); // 文件选择 fileselect.addEventListener("change", FileSelectHandler, false); // XHR2是否可用? var xhr = new XMLHttpRequest(); if (xhr.upload) { // 文件拖放 filedrag.addEventListener("dragover", FileDragHover, false); filedrag.addEventListener("dragleave", FileDragHover, false); filedrag.addEventListener("drop", FileSelectHandler, false); filedrag.style.display = "block"; // 移除提交按钮 submitbutton.style.display = "none"; } }
Init()函数:1. 为文件输入元素设置“change”事件监听器。2. 显示#filedrag元素。3. 设置“dragover”和“dragleave”事件监听器以更改#filedrag元素的样式。4. 为#filedrag元素设置“drop”事件监听器。5. 隐藏表单提交按钮——因为我们将分析和上传所选文件,所以不需要它。
可以选择在支持文件拖放时隐藏文件输入元素。就我个人而言,我更喜欢同时提供这两种选项,因为拖放会带来一些可用性问题。XMLHttpRequest.upload方法检查可以防止Opera中的问题。浏览器支持File、FileList和FileReader,但不支持拖放事件或XMLHttpRequest2。因此,它可以显示文件信息,但我们不想显示#filedrag元素或移除提交按钮。
文件拖放样式更改
很少有人在Web浏览器中体验过文件拖放。事实上,经验丰富的Web用户可能认为这是不可能的。因此,我们使用了一个声明“将文件拖放到此处”的元素。我们还希望通过更改其样式来指示何时将文件拖放到#filedrag位置:
// 文件拖放悬停 function FileDragHover(e) { e.stopPropagation(); e.preventDefault(); e.target.className = (e.type == "dragover" ? "hover" : ""); }
分析已拖放或已选择的文件
无论使用“浏览”选择一个或多个文件还是将文件拖放到#filedrag位置,我们都使用相同的FileSelectHandler()函数:
// 文件选择 function FileSelectHandler(e) { // 取消事件和悬停样式 FileDragHover(e); // 获取FileList对象 var files = e.target.files || e.dataTransfer.files; // 处理所有File对象 for (var i = 0, f; f = files[i]; i++) { ParseFile(f); } }
该函数:1. 调用FileDragHover()以移除悬停样式并取消浏览器事件。这至关重要,否则浏览器可能会尝试显示文件。2. 获取FileList对象。这将来自文件输入框(e.target.files)或#filedrag元素(e.dataTransfer.files)。3. 最后,该函数循环遍历FileList中的所有File对象,并将其作为参数传递给ParseFile()函数……
<fieldset><legend>HTML文件上传</legend> <div> <input type="file" id="fileselect" name="fileselect[]" multiple="multiple"> <label for="fileselect">选择要上传的文件:</label> <div id="filedrag">或将文件拖放到此处</div> </div> <input type="submit" value="上传文件" id="submitbutton"> </fieldset> <div id="messages">状态信息</div>
该函数使用File对象提供的三个主要只读属性输出信息:-.name:文件名(不包含路径信息)-.type:MIME类型,例如image/jpeg、text/plain等-.size:文件大小(以字节为单位)。
请在Firefox、Chrome或Opera中查看演示页面(无拖放支持)。您还可以下载文件以检查代码。我们已经涵盖了很多内容。在我的下一篇文章中,我们将了解如何使用HTML5和JavaScript打开已拖放的文件……本文也已翻译成亚美尼亚语如果您喜欢阅读这篇文章,您会喜欢Learnable;在大师那里学习最新技能和技术的场所。会员可以立即访问所有SitePoint的电子书和交互式在线课程,例如面向现实世界的HTML5和CSS3。本文的评论已关闭。您有关于HTML5的问题吗?为什么不在我们的论坛上提问呢?关于HTML5文件拖放的常见问题解答(FAQ)*
(以下FAQ部分由于篇幅过长,已省略。 如果需要,可以单独请求FAQ部分的翻译。)
以上是如何使用HTML5文件拖放的详细内容。更多信息请关注PHP中文网其他相关文章!