相信很多使用过GMail的读者都会觉得它的文件上传功能作得好,首先它支持无刷新上传,其次它能够隐去丑陋的文件上传框。本期的Random Clipping重点推荐两篇与上传有关的英语技术文章,希望对大家制作一个GMail那样的上传界面有所帮助。
美化文件上传框 (Styling an input type="file")
"Of all form fields, the file upload field is by far the worst when it comes to styling",意思是“对于所有的表单栏目,在谈论到美化时文件上传框是至今为止最烂的一个”,因此这篇文章要讲的就是如何美化文件上传框。
接着文章分为若干个小节清晰的描述了美化的过程,以及浏览器兼容性的问题,QuirksMode.org那些工整而漂亮的排版详细会让你乐于看下去:
- The Problem - 问题来源。"The designer wanted the same styles, plus a "Select" image, to apply to all file upload fields",设计师想要(和文本框)一样的样式,以及一个“浏览”按钮的图片,这就是问题的来源。
- The solution - 解决方案。一位名为Michael McGrady的读者发明了一个技巧来允许我们美化文件上传框。"McGrady's technique is elegant in its simplicity",这为读者提供的技术因为其简单而优雅。我们看看这个优雅的技巧是怎么做的,别忘记了在上期Random Clipping讲到的阅读方法哦,也就是看关键字并借助自己的技术背景来理解:
- "Take a normal ... put it in ... with ...",也就是把一个普通的文件上传框放到一个带有position:relative的元素中。
- "... add a normal <input> and an image ... Position ... absolutely ...",在上述父元素中,放置一个普通的<input>和一张图片,设置position:absolute,将它们定位到刚刚好覆盖在文件上传框上面。
- "Set the z-index of ... to 2 ... it lies on top of ...",设置文件上传框的z-index:2,这样它就在另外两个元素的上面了。
- "... set the opacity ... to 0 ...",设置文件上传框透明度为0,这样你看到的就是下面的文本框和图片,然而点击到的却是上方的文本上传框。
- "When ... fake input field shoud ...",当文件上传框选择了文件的时候,那个文本框要能正确显示文件路径,这需要JavaScript来实现。
- The HTML/CSS structure - HTML/CSS结构。这里列举了作者所用的HTML/CSS,代码你可以跳过不看,但下面的说明你不可不看,除非你看代码时能够一眼看穿每一个CSS属性在整个技巧上的意义。
- Why JavaScript? - 为什么选择JavaScript?"I decided to go for a strict JavaScript solution",作者说,“我决定选择一个严格的JavaScript解决方案”,他的意思是直接用JavaScript来生成上述步骤所需的一切,而非采用声明的方式。具体实现方式他放在最后了,先说说他给出的三个选择JavaScript理由:
- "... we need JavaScript anyway to copy ...",反正我们要用JavaScript去负值地址到文本框。
- "... avoid meaningless extra HTML ...",避免无意义的额外的HTML。
- 浏览器兼容性问题,作者给出了允许在Netscape4/Explorer4/Netscape3的截图,说明多出来的文本框和图片在这些对CSS支持甚少且怪异的古董浏览器上会变得怎样,而解决方案自然是让JavaScript来生成这些元素,古董浏览器不支持W3C DOM也就仅显示应有的普通文件上传框。
- Problems and extensions - 问题与扩展。"One problem remains: the user can't choose not to upload a file after all",意思是“有一个问题仍未解决:用户操作完后不能选择取消上传文件”。这个很容易理解,上传文件框的安全性限制极严,在JavaScript中我们无法手动改变其路径,也就无法将用户在文本框中对路径的修改应用到文件上传框中。想知道作者怎么解决这个问题的,自己看看就知道了。
无刷新文件上传 (Uploading files without a full postback)
作者是Luis Abreu,和众多使用ASP.NET AJAX的开发人员一样,对于框架本身不提供一个无刷新上传文件的实现而感到不爽,所以决定自己做一个。我们都知道AJAX无法实现文件上传,而且也能了解到隐藏IFrame就是至今为止最好的无刷新文件上传方式(至少GMail也是这样做的),所以要自己做一个的难度就在于如何设计一整套的解决方案。
Luis Abreu在这篇文章中就给出了整套的解决方案,从客户端负责动态创建和删除Iframe的Behavior到服务器端负责接收文件的IHttpHandler,还包括处理上传错误的IHttpModule和服务器端扩展用的Extender。
这篇文章看起来很长,其实是因为它嵌入的代码很多,这时候英语阅读能力成为了次要的,而技术背景和代码阅读能力决定了你是否能理解这个解决方案的实现方式,阅读变成了通过英语的描述来帮助理解代码。
另外,我自己也正在做一个类似的服务器端控件,希望能够做到像GMail那样的效果并且灵活易用,但不依赖于ASP.NET AJAX。现在客户端代码基本上写完了,准备开始写服务器端接收文件的代码。写好之后我会在Most Pratical栏目放出,你可以通过订阅Cat in dotNET以关注该栏目。