3

我正在尝试实现一个 UI,它可以让最终用户在自定义 UI 上上传多个文件到服务器上——与 GMail 或 Outlook.net 的做法几乎相同。

要节点的几件事:

  1. <input type="file">是丑陋的 - 并且不标准(IE 在文件名的左侧显示一个名为“浏览”的按钮。Chrome 在文件名的右侧显示一个名为“选择”的按钮)。
  2. 大多数关于如何执行 UI 的建议都建议使用 隐藏输入文件元素opacity=0,但在自定义 UI 之上。'click' 事件将打开对话框,返回后文件名(不包括路径)将以 $('#file').val() 的形式提供。请参阅问题以及jsfiddle上的示例。
  3. 我也知道 HTML5multiple="multiple"现在有一个属性,它可以让用户选择多个文件。
  4. 但是,我正在寻找一种多文件解决方案,它适用于 IE8 及更高版本(以及 WebKit、Mozila)。
  5. 有人建议 Google 使用 Flash。这不是真的。当 Flash 被禁用时,他们的多文件上传工作。

现在,这是我最大的惊喜:在 IE 和 Chrome 上使用开发人员工具 (F12),同时查看 GMail 和 Outlook.NET——这两种实现在树中都没有<input type='file'>元素(据我所知)。此外,这两种实现都适用于 IE8(禁用闪存)。

到底是怎么回事?他们是如何做到的呢?

编辑:为什么我认为他们不使用文件输入元素?打开开发者工具(F12),切换到控制台,输入:document.getElementsByTagName('input'). 有 24 个输入元素,其中 19 个是 type=hidden,没有一个是 type=file。

编辑2:感谢所有响应者和评论员。确实-下面的“没有其他方法”论点(评论中)是有效的。事实证明,Outlook.NET 和 GMail 都会有一个<input type='file'>元素,它们只会在用户单击“附加文件”按钮时动态添加。然后,他们将向元素发送一个“点击”事件,这将触发选择文件对话框。

见证这一点,使用 F12 开发工具(在 Chrome 中或在 IE 中),并在交互式控制台中键入:document.querySelectorAll('input[type=file]')。请注意,在这两种实现中,元素都是 body 的直接子元素(display=none)。

他们使用 iframe 进行上传(与下面唯一的答案不同),但可以使用简单的 XHR 代码上传,现在可以使用 HTML5。

网上最好的资源是:https ://developer.mozilla.org/en-US/docs/Using_files_from_web_applications 。我已经完成了下面@Jay 的步骤(很棒),但是 Mozilla 页面更简单,这是我的建议。另外,快速查看@Niranjan 评论上的 jsfiddle 示例。

4

1 回答 1

2

我最近为一个旧的 asp.net 网站实现了一个多文件上传 UI,但概念应该是相同的。

我不是很擅长写作(总结代码),但就这样吧。

  1. 创建多个 IFrame。由于安全限制,我在加载文档后尝试编写 IFrame 时遇到了问题,因此服务器渲染的数量与用户一次使用的数量一样多。

  2. 添加一个“上传”按钮和处理程序,它首先将load处理程序添加到其中一个 iframe。

    var frame = $('iframe:first');

在框架负载处理程序中---

frame.load(function () { /* all the code below* /});

2.a. 像这样将文件的输入标签以及您喜欢的其他元素写入框架

frame.contents().find('body').html("html goes here");

2.b。现在将处理程序添加到框架中的文件输入并提交该表单:

frame.contents().find('#fileUpload').change( /*submit the form */)

2.c。现在调用文件上传对话框

frame.contents().find('#fileUpload').click();

2.d。现在该行将阻塞,直到对话框返回。当它发生时,您必须检查文件上传控件的值,null以防它们被取消。这是我将 iframe 标记为未使用的地方。

2.e. 以太网方式,您需要从 iframe 的加载中解除绑定并重新绑定到将处理返回的不同方法(上传完成)

frame.unbind('load');
frame.load(function () { /* handle file uploaded */})

2.e.1。这是我向用户报告成功并释放框架以便可以重复使用的地方。

2.e.2。最后从上传完成方法再次解除加载绑定

所有这些都在您的帧加载处理程序中

3.现在使框架加载

frame.load();

至少我是这样做的。我将所有文件上传到一个处理程序,该处理程序报告文件%,并且父页面内的循环触发了 ajax 获取并显示每个文件的进度。

主要思想是,如果您想以“ajaxy”样式上传多文件,但不使用 Flash 或 Html 5,则需要使用 iframe 集合和一些花哨的脚本。

希望这可以帮助。

于 2013-06-20T21:46:10.890 回答