`

定制jQuery File Upload为微博式单文件上传

阅读更多

定制jQuery File Upload为微博式单文件上传

jQuery File Upload是一个非常优秀的上传组件,主要使用了XHR作为上传方式,并且利用了相当多的现代浏览器功能,所以可以实现诸如批量上传、超大文件上传、图片预览、拖拽上传、上传进度显示、跨域上传等功能。

 

美中不足的是jQuery File Upload的默认UI比较复杂,集成了全部功能,让jQuery File Upload的定制变得比较繁琐。

 

尝试用jQuery File Upload制作了一个类似微博图片上传的单文件式上传Demo,将一些要点记录下来备忘。最终效果如下图:

 

jQuery File Upload Demo

 

jQuery File Upload的最简模型

 

jQuery File Upload包含了一堆文件,首先需要弄清楚的是最核心的部分是哪些,根据官方的例子可以知道,一个最简单的jQuery File Upload上传组件,必须包括以下文件:

 

  • jQuery核心库,建议使用jQuery 1.8以上版本
  • js/vendor/jquery.ui.widget.js : jQuery UI Widget
  • js/jquery.iframe-transport.js : 扩展iframe数据传输
  • js/jquery.fileupload.js : jQuery File Upload核心类
  • js/cors/jquery.xdr-transport.js 在IE下应载入此文件解决跨域问题

 

此时只需要加载一个上传按钮

 

<input id="fileupload" type="file" name="files[]" data-url="server/php/" multiple>

 

以及一行代码

 

$('#fileupload').fileupload();

 

就完成了一个最基本的上传组件。这个最简单的上传组件可以将选中的文件以表单形式提交到data-url约定的URL,同时提供了足够多的设置和基础事件可供扩展。

 

jQuery File Upload的简单扩展

 

对于最简模型,稍加扩展就可以实现一些比较常用的功能,比如可以在上传完毕后可以显示一个简单的结果:

 

$('#fileupload').fileupload({
    done: function (e, data) {
        $.each(data.result, function (index, file) {
            $('<p/>').text(file.name + ' uploaded').appendTo($("body"));
        });
    }
});

 

或者显示上传进度,配合一些进度条组件就可以构成一个上传进度条

 

$('#fileupload').fileupload('option', {
    progressall: function (e, data) {
        var progress = parseInt(data.loaded / data.total * 100, 10);
        console.log(progress + '%');
    }
});

 

等等。只要多阅读手册就可以配合项目做更具体的扩展开发。

 

XHR响应为Json时IE的下载BUG

 

这里需要特别注意的是,由于jQuery File Upload都是采用XHR在传递数据,服务器端返回的通常是JSON格式的响应,但是IE会将这些JSON响应误认为是文件传输,然后直接弹出下载框询问是否需要下载。

 

解决这个问题的方法是必须将相应的Http Head从

 

Content-Type: application/json

 

更改为

 

Content-Type: text/plain

 

具体的实现根据服务端不同有所区别,比如ZF2中可以在Controller中这样写:

 

 $this->getServiceLocator()->get('Application')->getEventManager()->attach(\Zend\Mvc\MvcEvent::EVENT_RENDER, function($event){
     $event->getResponse()->getHeaders()->addHeaderLine('Content-Type', 'text/plain');
 }, -10000);

 

这也是我在stackoverflow上的对ZF2更改最终响应类型的一个回答

 

jQuery File Upload UI的构成与说明

 

为了引入更多功能,jQuery File Upload在上面最简模型的基础上又实现了一套jQuery File Upload UI,也就是官方给出的最终Demo,这套UI额外提供了以下功能:

 

  • 最大/最小文件限定 Options.maxFileSize / Options.mixFileSize
  • 文件类型限定,通过正则表达式检测文件名实现 Options.acceptFileTypes
  • 选择文件后自动上传 Options.autoUpload
  • 上传文件数量限制,通过上传后将选择文件按钮置为Disabled实现 Options.maxNumberOfFiles
  • 上传模板,就是选择文件后显示预览的html代码 Options.uploadTemplate
  • 下载模板,当文件上传完毕后显示的html代码 Options.downloadTemplate

 

等等,同时还增加了一系列新的接口和事件,具体都可以查阅官方手册。

 

具体对应到文件为:

 

  • JavaScript-Templates : JS模板引擎
  • JavaScript-Load-Image : 图片预览功能
  • js/jquery.fileupload-ui.js & css/jquery.fileupload-ui.css : UI核心类,CSS可以替换旧式的上传控件为统一的按钮
  • js/jquery.fileupload-fp.js:进度条扩展功能

 

也许正是因为附加功能太多,各功能之间耦合非常重,jQuery File Upload UI显得不够友好,主要体现在:

 

  • 上述功能均无法拆分,必须统一全部加载
  • 各功能需要界面存在相应元素,如果缺少某些元素,包括JS模板内的元素,整个UI无法正常工作
  • JS模板引擎对标签配对非常严格,标签如果遗漏也有可能引起UI无法正常工作

 

所以经验之谈是,在定制jQuery File Upload UI时,如果UI无法工作。首先检查js文件是否全部加载,然后检查页面元素是否齐全,再次检查JS模板标签是否严格配对,最后还可以查看页面是否有重复调用fileupload()方法。

 

jQuery File Upload UI构成元素

 

UI的部件都是硬编码的HTML class,无法更改。核心的几个部件为

 

全局控制按钮 (必须)

 

    <div class="fileupload-buttonbar">
            <span class="fileinput-button"><input type="file" name="files[]" multiple></span>
            <button type="submit" class="start">Start upload</button>
            <button type="reset" class="cancel">Cancel upload</button>
            <button type="button" class="delete">Delete</button>
            <input type="checkbox" class="toggle">
    </div>

 

最外层容器为.fileupload-buttonbar,内部包含

 

  • 文件选择按钮 .fileinput-button (必须),内部必须包裹一个input:file
  • 开始上传按钮 .start
  • 取消上传按钮 .cancel
  • 删除按钮 .delete
  • 文件勾选按钮 .toggle

 

整体上传进度 (可选)

 

<div class="fileupload-progress">
    <div class="progress">
        <div class="bar" style="width:0%;"></div>
    </div>
    <div class="progress-extended"></div>
</div>

 

最外层容器为.fileupload-progress,内部包含

 

  • 上传进度条容器.progress
  • 上传进度条 .bar
  • 上传进度文本 .progress-extended

 

文件显示容器 (必须)

 

<div class="files"></div>

 

.file容器是最重要的UI部件,上传时的文件预览模板以及上传完毕后的文件显示模板都将显示在这里。

 

文件预览模板 (必须)

 

<script id="template-upload" type="text/x-tmpl">
{% for (var i=0, file; file=o.files[i]; i++) { %}
<div class="template-upload">
    {% if (file.error) { %}
        <div class="error">{%=file.error%}</div>
    {% } else { %}
    <div class="preview"><span class="fade"></span></div>
    <div class="name"><span>{%=file.name%}</span></div>
    <div class="size"><span>{%=o.formatFileSize(file.size)%}</span></div>
    <div class="progress progress-success progress-striped active" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0" style="height:5px;"><div class="bar" style="width:0%;"></div></div>
    <span class="start">
        {% if (!o.options.autoUpload) { %}
            <button>Start Upload</button>
        {% } %}
    </span>
    {% } %}
    <span class="cancel"><button>Cancel</button></span>
</div>
{% } %}
</script>

 

这部分逻辑不难读懂,由于文件选择是多选的,所以被选择文件一开始以数组方式存放,循环输出。即使我们加入最大文件只能上传一个,这里得到的仍然是数组形式。

 

当文件有任何错误时,如文件类型被禁止,文件大小不符合约定,会得到file.error。文件检测没有问题,则可以用以下元素控制当前文件:

 

  • 开始上传当前文件按钮.start (必须)
  • 取消上传当前文件按钮.cancel (可选)
  • 当前文件上传进度.progress (可选)

 

上传后文件回调显示模板 (必须)

 

<script id="template-download" type="text/x-tmpl">
{% for (var i=0, file; file=o.files[i]; i++) { %}
<div class="template-download">
    {% if (file.error) { %}
        <div class="error">{%=file.error%}</div>
        <span class="cancel"><button class="btn btn-block"><i class="icon-ban-circle"></i>Cancel</span>
    {% } else { %}
    <div class="preview"><img src="{%=file.thumbnail_url%}"></div>
    <div class="name"><span>{%=file.name%}</span></div>
    <div class="size"><span>{%=o.formatFileSize(file.size)%}</span></div>
    <div class="delete"><button data-type="{%=file.delete_type%}" data-url="{%=file.delete_url%}">Delete</button>
    </div>
    {% } %}
</div>
{% } %}
</script>

 

这一部分的o.files完全来自服务器端的json响应,所以模板内容可以自由发挥。唯一被定制的元素为删除按钮.delete。 点击这个按钮会向按钮中指定的url发送请求,比如

 

<div class="delete"><button data-type="DELETE" data-url="/file/1">Delete</button></div>

 

点击后则会用DELETE方式发送HTTP请求

 

DELETE /file/1

 

jQuery File Upload UI工作流程

 

有了上面罗列的UI元素,就可以拼凑出一个简单的jQuery File Upload UI工作流程:

 

  1. 用户点击.fileinput-button选择要上传的文件(多个)
  2. 文件选择后,文件信息被整理为数组置入文件预览模板#template-upload
  3. 模板引擎循环处理文件信息并生成模板.template-upload
  4. 每生成一个模板,模板就被插入到文件显示容器.files的最后。
  5. 用户点击上传按钮.start上传,文件信息被转换为XHR请求至服务器端
  6. UI获得服务器端生成JSON响应文件
  7. JSON响应信息也被整理成数组置入回调显示模板#template-download
  8. 模板引擎循环处理文件信息并生成模板.template-download
  9. 每生成一个模板,会将此模板替换对应的.template-upload部分

 

定制过程

 

有了上面的基础,要个性化的定制jQuery File Upload就简单了很多:

 

限制文件类型

 

由于没有使用Flash空间,上传的文件选择框是无法限制文件类型的,所以所谓的限制文件类型,只能让用户选择文件之后,用file.error显示一个错误信息。例如本次需要限定可上传的文件为图片,那么Options指定:

 

acceptFileTypes:  /(\.|\/)(gif|jpe?g|png)$/i

 

即可。

 

在Google Chrome浏览器中,可以用input:file原生支持文件类型限定,可以配合使用:

 

<input type="file" name="upload[]"  accept="image/png, image/gif, image/jpg, image/jpeg">

 

不过在客户端做再多的限定也只是提升用户体验,不能真正保证安全性,所以不要忘记了在服务器端做同样的类型检测。

 

文件数量限制

 

只需在Options指定

 

maxNumberOfFiles : 1

 

即可。jQuery File Upload UI的处理方式是当用户上传一个文件后,文件选择按钮被置为Disabled。

 

这同样只是客户端的小把戏,真正想要严格的约束用户只能上传一个文件还是需要在服务器端通过Session做更加复杂的控制。

 

文件大小限制

 

Options中指定

 

maxFileSize: 5000000

 

即只允许单文件最大5MB。

 

Firefox disable bug

 

在Firefox环境下测试是,发现如果将文件数量限制为1,选择一次文件,刷新页面之后文件选择按钮会莫名其妙的被加上一个Disabled属性,导致无法点击。所以最终我们的初始化代码为:

 

var uploader = $("#fileupload");
uploader.fileupload({
    dataType: 'json',
    autoUpload: false,
    acceptFileTypes:  /(\.|\/)(gif|jpe?g|png)$/i,
    maxNumberOfFiles : 1,
    maxFileSize: 5000000 
});
uploader.find("input:file").removeAttr('disabled');

 

最后就是界面的一些调整,完整代码在EvaEngine的File模块下,点击查看.

分享到:
评论

相关推荐

    jQuery File Upload演示与下载

    其中,jQuery File Upload插件是处理文件上传问题的一个高效解决方案,尤其在需要进行多文件上传、进度显示、预览等复杂操作时,它的优势尤为明显。本文将深入探讨jQuery File Upload的原理、使用方法以及实际应用。...

    jQuery File Upload 基于Jquery的图片上传组件

    **jQuery File Upload** 是一个强大的基于 **jQuery** 的图片上传插件,专为网页上的文件上传功能设计。它提供了一套完整的解决方案,包括多文件选择、上传进度显示、取消与删除上传任务、预览上传图片等功能,使得...

    asp.net jquery file upload

    总的来说,"asp.net jquery file upload"是利用ASP.NET的服务器端处理能力、jQuery的客户端交互性以及Flash的文件上传功能,构建出一种高效、友好的多文件上传解决方案。这种技术尤其适用于需要大量文件交互的Web...

    jQuery-File-Upload

    在网页应用中,图片上传功能是不可或缺的一部分,而jQuery File Upload插件则为开发者提供了一个强大且易用的解决方案。这款插件以其丰富的特性、广泛的语言支持以及优秀的用户体验设计,赢得了开发者们的青睐。本文...

    jQuery File Upload 可跨域的多图片上传

    `jQuery File Upload` 是一个流行的JavaScript库,它允许用户在网页上实现多文件上传功能,特别是支持跨域上传,这对于现代Web应用来说至关重要。该框架以其易于使用、高度可定制化以及对HTML5 API的良好支持而受到...

    Jquery Large File Upload (Jquery实现大文件上传).rar

    综上所述,`jQuery Large File Upload` 是一个集成了多种技术的文件上传解决方案,它结合了jQuery的便利性和HTML5的新特性,为开发者提供了方便的工具,以实现高效、可靠的大文件上传功能。通过学习和使用这个项目,...

    jQuery-File-Upload插件

    jQuery File Upload是一款强大的基于jQuery的文件上传插件,它提供了多文件选择、进度条显示、预览、上传取消以及删除等功能。这款插件利用HTML5技术,为现代浏览器提供了先进的文件上传体验,同时通过优雅降级的...

    jQuery File Upload 9.5.0 上传插件 非常好用

    1. **异步上传**:jQuery File Upload支持后台无刷新上传,用户可以继续浏览页面,而文件在后台上传,提升用户体验。 2. **多文件选择**:用户可以一次性选择多个文件进行上传,提高上传效率。 3. **进度显示**:...

    jQuery-File-Upload asp.net MVC3 Demo

    "jQuery-File-Upload" 是一个著名的前端文件上传插件,尤其在Web开发领域中广泛应用。这个插件基于JavaScript库jQuery,提供了强大的功能,如多文件选择、文件预览、进度条显示、取消上传以及大文件分块上传等。在这...

    jQuery File Upload

    **jQuery File Upload** 是一个基于JavaScript的开源上传插件,专为jQuery框架设计,用于实现高效、可扩展的多文件上传功能。这个插件利用HTML5的File API,同时兼容那些不支持该API的浏览器,确保了广泛的应用性。...

    Jquery file upload Mvc4.0实例

    【jQuery File Upload】是jQuery的一个插件,用于在网页上实现文件上传功能,它支持多文件选择、进度条显示、预览以及异步上传。在Mvc4.0框架下,结合jQuery File Upload可以构建高性能、用户体验优秀的文件上传系统...

    jquery-file-upload案例

    在当今的Web开发中,用户界面往往需要处理文件上传功能,这使得jQuery File Upload插件成为一个重要的工具。本篇文章将深入探讨如何利用jQuery File Upload库,结合Java后端,实现高效、友好的文件上传功能。 ...

    file-upload

    jQuery File Upload是一个流行的JavaScript库,专为处理文件上传而设计。它提供了丰富的特性,如多文件选择、上传取消、文件删除,以及在上传前生成缩略图预览等功能。这些特性极大地提升了用户在交互过程中的满意度...

    jQuery-file-upload的各种语言拖拽上传文件功能

    《jQuery-file-upload:实现跨语言的拖拽上传文件功能》 在现代Web开发中,用户交互体验至关重要,其中文件上传是常见的功能之一。jQuery-file-upload是一个强大的jQuery插件,它支持多语言、拖拽上传等多种特性,...

    文件上传插件(jQuery-File-Upload)

    以上是关于jQuery-File-Upload插件的详细介绍,它在现代Web应用中扮演着重要角色,为用户提供高效、可靠的文件上传解决方案。无论是个人项目还是企业级应用,都可以考虑采用此插件来提升文件上传体验。

    jQuery-File-Upload for asp.net MVC

    《jQuery-File-Upload在ASP.NET MVC中的应用详解》 在Web开发中,文件上传功能是必不可少的一部分,尤其是...总的来说,jQuery-File-Upload与ASP.NET MVC的结合,为我们提供了一个强大且易于使用的文件上传解决方案。

    jQuery-File-Upload-master

    在Web开发中,文件上传功能是一项常见的需求,而jQuery File Upload则是实现这一功能的一款强大插件。本篇文章将深入探讨jQuery File Upload的核心特性、工作原理以及如何在实际项目中进行应用。 jQuery File ...

    jquery_file_upload 可运行

    `jQuery File Upload` 是一个流行的前端文件上传组件,它允许用户在网页上实现优雅、功能丰富的多文件上传功能。这个组件结合了`jQuery`库的强大功能,提供了易于使用的API和高度自定义的界面,适用于各种Web应用...

    jQuery-File-Upload-9.9.2.zip

    jQuery File Upload 9.9.2是一款优秀的JavaScript插件,它为开发者提供了高效、易用且功能丰富的文件上传解决方案。这款插件以其高度的兼容性、多文件选择与拖放上传的特性,以及用户友好的预览和进度反馈机制,深受...

Global site tag (gtag.js) - Google Analytics