我正在尝试实现一个UI,让最终用户在自定义用户界面上上传多个文件服务器 - 就像GMail或Outlook.net一样。
节点很少:
<input type="file">
很丑陋 - 而不是标准(IE在文件名左侧显示名为“浏览”的按钮.Chrome在文件名右侧显示名为“选择”的按钮。)< / LI>
opacity=0
隐藏输入文件元素,但最好是使用自定义用户界面。 'click'事件将打开对话框,返回时文件名(没有路径)将作为$('#file')。val()。请参阅this问题,以及jsfiddle上的示例。multiple="multiple"
属性,可以让用户选择多个文件。现在,我最大的惊喜是:在IE和Chrome上使用开发人员工具(F12),同时查看GMail和Outlook.NET - 两个实现都没有<input type='file'>
元素树(据我所知)。此外,这两种实现都适用于IE8(禁用闪存)。
发生了什么事?他们是怎么做到的?
编辑:为什么我认为他们不使用文件输入元素?打开开发人员工具(F12),切换到控制台,键入:document.getElementsByTagName('input')
。有24个输入元素,其中19个是type = hidden,none是type = file。
编辑2:谢谢所有响应者和评论员。确实 - 下面的“没有别的办法”论点(在评论中)是有效的。事实证明,Outlook.NET和GMail都有一个<input type='file'>
元素,只有当用户点击“附加文件”按钮时,它们才会动态添加。然后,他们将向元素发送“click”事件,这将触发选择文件对话框。
见证这一点,使用F12开发工具(在Chrome或IE中),并在交互式控制台中输入:document.querySelectorAll('input [type = file]')。请注意,在两个实现中,元素都是body的直接子元素(display = none)。
他们不使用iframe进行上传(与下面的唯一答案不同),但现在可以在HTML5中上传简单的XHR代码。
网上有关如何执行此操作的最佳资源是:https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications。我已经完成了以下@Jay的步骤(这很棒),但Mozilla页面更简单,这是我的推荐。另外,快速浏览@Niranjan评论中的jsfiddle示例。
答案 0 :(得分:2)
我最近为旧的asp.net网站实现了一个多文件上传UI,但概念应该是相同的。
我不擅长写作(总结代码),但现在就去了。
创建多个IFrame。由于安全限制,我在加载文档后尝试编写IFrame时遇到问题,因此,尽管用户会立即使用,但服务器的渲染次数仍然很多。
添加“上传”按钮和处理程序,该按钮和处理程序首先将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和一些花哨的脚本集合。
希望这有帮助。