将文件从桌面拖放到浏览器是Web应用程序集成的最终目标之一。 这是由四部分组成的系列文章中的第一篇,描述了如何:
- 允许将文件拖放到网页元素上
- 分析JavaScript中删除的文件
- 在客户端上加载和解析文件
- 使用XMLHttpRequest2异步将文件上传到服务器
- 在进行上传时显示图形进度条
- 使用渐进增强功能来确保您的文件上传表单可以在任何浏览器中使用(对所有IE6爱好者来说都是好消息!)
- 不用库就可以用普通的JavaScript编写代码。
ew
大,差的浏览器支持
在开始之前,本教程将介绍几种最先进的HTML5技术,因此希望对它的支持是不完整的。 该代码可在今天使用,但API可能会更改,浏览器也会发展。
- Firefox和Chrome的最新版本支持所有功能,并且运行完美。
- Opera可以使用JavaScript解析文件,但是未实现文件删除和XMLHttpRequest2上传。
- IE和Safari的桌面版本不支持任何API。
- 苹果已在Safari的iPhone和iPad版本上禁用了HTML文件上传表单。 有人知道为什么吗?
最后,请注意,我的代码显示了基本概念。 几乎没有错误检查,您需要对其进行调整以适合生产系统。
HTML和CSS
这是带有文件输入类型的标准格式。 HTML5唯一的功能是“ multiple”属性,该属性允许用户选择任意数量的文件。
我们将文件上传到运行PHP的服务器上,但是无论您使用哪种技术,代码都几乎相同。 隐藏的MAX_FILE_SIZE值指定300,000字节-PHP使用此值,但我们还将在客户端进行检查以防止上传大量文件。
<form id="upload" action="upload.php" method="POST" enctype="multipart/form-data">
<fieldset>
<legend>HTML File Upload</legend>
<input type="hidden" id="MAX_FILE_SIZE" name="MAX_FILE_SIZE" value="300000" />
<div>
<label for="fileselect">Files to upload:</label>
<input type="file" id="fileselect" name="fileselect[]" multiple="multiple" />
<div id="filedrag">or drop files here</div>
</div>
<div id="submitbutton">
<button type="submit">Upload Files</button>
</div>
</fieldset>
</form>
<div id="messages">
<p>Status Messages</p>
</div>
#filedrag元素将用作我们文件的拖放位置。 该元素在CSS中是隐藏的,但是如果支持拖放,它将在JavaScript中启用:
#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 File API提供了几个对象。 我们将使用:
- FileList :代表所选文件的数组。
- File :代表一个单独的文件。
- FileReader :一个接口,使我们可以在客户端上读取文件数据并在JavaScript中使用它。
附加JavaScript事件
是时候使用一些JavaScript来弄脏我们了。 我们没有使用JavaScript库,因此,为了节省打字的手指,我们将创建几个帮助函数,以按ID返回元素并输出状态消息:
// getElementById
function $id(id) {
return document.getElementById(id);
}
//
// output information
function Output(msg) {
var m = $id("messages");
m.innerHTML = msg + m.innerHTML;
}
现在,我们将检查File API是否可用,并调用Init()函数:
// call initialization file
if (window.File && window.FileList && window.FileReader) {
Init();
}
//
// initialize
function Init() {
var fileselect = $id("fileselect"),
filedrag = $id("filedrag"),
submitbutton = $id("submitbutton");
// file select
fileselect.addEventListener("change", FileSelectHandler, false);
// is XHR2 available?
var xhr = new XMLHttpRequest();
if (xhr.upload) {
// file drop
filedrag.addEventListener("dragover", FileDragHover, false);
filedrag.addEventListener("dragleave", FileDragHover, false);
filedrag.addEventListener("drop", FileSelectHandler, false);
filedrag.style.display = "block";
// remove submit button
submitbutton.style.display = "none";
}
}
Init()函数:
- 将“更改”事件侦听器设置为文件输入元素。
- 显示#filedrag元素。
- 设置“拖动”和“拖动”事件侦听器以更改#filedrag元素的样式。
- 为#filedrag元素设置“放置”事件侦听器。
- 隐藏表单提交按钮-这不是必需的,因为我们将在选择文件后对其进行分析和上传。
(可选)可以在支持文件拖动时隐藏文件输入元素。 就个人而言,我宁愿同时提供这两种选择,因为拖放会引起许多可用性问题。
XMLHttpRequest.upload方法检查可防止Opera中出现问题。 浏览器支持File,FileList和FileReader,但不支持拖放事件或XMLHttpRequest2。 因此,它可以显示文件信息,但我们不想显示#filedrag元素或删除提交按钮。
文件放置样式更改
很少有人在Web浏览器中经历过文件拖放操作。 实际上,有经验的Web用户可能不会认为这是不可能的。 因此,我们使用了一个表示“在此处放置文件”的元素。 我们还想通过更改样式来指示何时将文件拖到#filedrag位置上:
// file drag hover
function FileDragHover(e) {
e.stopPropagation();
e.preventDefault();
e.target.className = (e.type == "dragover" ? "hover" : "");
}
分析删除或选择的文件
无论使用“浏览”选择一个或多个文件还是将其拖到#filedrag位置,我们都使用相同的FileSelectHandler()函数:
// file selection
function FileSelectHandler(e) {
// cancel event and hover styling
FileDragHover(e);
// fetch FileList object
var files = e.target.files || e.dataTransfer.files;
// process all File objects
for (var i = 0, f; f = files[i]; i++) {
ParseFile(f);
}
}
功能:
- 调用FileDragHover()删除悬停样式并取消浏览器事件。 这是必不可少的,否则浏览器可能会尝试显示文件。
- 获取一个FileList对象。 这可以来自文件输入框(e.target.files)或#filedrag元素(e.dataTransfer.files)。
- 最后,该函数循环遍历FileList中的所有File对象,并将其作为参数传递给ParseFile()函数…
function ParseFile(file) {
Output(
"<p>File information: <strong>" + file.name +
"</strong> type: <strong>" + file.type +
"</strong> size: <strong>" + file.size +
"</strong> bytes</p>"
);
}
该函数使用File对象提供的三个主要只读属性输出信息:
- .name :文件名(不包含路径信息)
- .type :MIME类型,例如图像/ jpeg,文本/纯文本等。
- .size :文件大小(以字节为单位)。
请在Firefox,Chrome或Opera中查看演示页面 (不支持拖放)。 您也可以下载文件以检查代码。
我们已经涵盖了很多基础。 在我的下一篇文章中,我们将发现如何使用HTML5和JavaScript打开拖放的文件 ……
本文也已翻译成亚美尼亚文
如果您喜欢阅读这篇文章,您会喜欢Learnable的 ; 向大师学习新鲜技能的地方。 会员可以立即访问所有SitePoint的电子书和交互式在线课程,例如针对真实世界的HTML5和CSS3 。
本文的评论已关闭。 对HTML5有疑问吗? 为什么不在我们的论坛上提问呢?