用jQuery File Upload做的上传控件demo,支持同页面多个上传按钮
需求
有这么一个需求,一个form有多个文件要上传,但又不是传统的图片批量上传那种,是类似下图这种需求,一开始是用的swfupload做的上传,但是问题是如果有多个按钮的话,就要写很多重复的代码,于为了代码的简洁所以就开始寻求其他的方法,期间试过uploadify,但是由于样式始终调不出来,最后就放弃了,直到发现这么个小巧的玩意,jQuery File Upload。
本文包含了upload的js实现,html的分析,css的实现等内容,文章末尾有git地址

最简运行时
官网下载的demo有N多js文件,一大堆js文件中只有几个才是必要的,其他的文件都是一些用不到的功能,只有在你需要的时候才需要引用。
<script src="http://libs.baidu.com/jquery/1.10.2/jquery.min.js" type="text/javascript"></script>
<script src="JS/jquery/jquery.iframe-transport.js"></script>
<script src="JS/jquery/jquery.ui.widget.js"></script>
<script src="JS/jquery/jquery.xdr-transport.js"></script>
<script src="JS/jquery/jquery.fileupload.js"></script>
其中iframe那个文件是为了进行iframe上传,ui文件是能选完文件自动上传的必要文件,xdr那个是在ie下才需要的,最后一个文件是主体
后台代码
新建一个ashx的文件,这里建立一个uploadHandler.ashx,然后写入如下代码,用于保存。
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
context.Response.Charset = "utf-8"; HttpPostedFile file = context.Request.Files["files"];
string uploadPath =
HttpContext.Current.Server.MapPath(@context.Request["folder"]) + "\\"; if (file != null)
{
if (!Directory.Exists(uploadPath))
{
Directory.CreateDirectory(uploadPath);
}
file.SaveAs(uploadPath + file.FileName);
//下面这句代码缺少的话,上传成功后上传队列的显示不会自动消失
string newName = file.FileName;
string oldName = file.FileName;
context.Response.Write("{\"newName\": \"" + newName + "\", \"oldName\": \"" + oldName + "\"}");
}
else
{
context.Response.Write("");
}
}
前台HTML
预览效果

最终的效果如上图所示,为了实现这个我们一步一步来分析。
DIV结构

如上图
- 作为整个控件的最外层
 - 是按钮
 - 是上传完成后显示的文件名(上传开始前隐藏)
 - 上传进度百分比(上传开始前隐藏)
 - 上传进度条(上传开始前隐藏)
 
上图后4个div按照顺序写在最外层里面,然后考虑通过浮动来解决位置的问题,当然也可以用绝对定位等方法来实现,这里选择了浮动。
因为要用到浮动,这里简单解释一下浮动的原理
首先设置0的宽度是280px
所以1的宽度就是70+margin-right:8 右侧还有202宽度,左浮动
2的宽度是150px,左浮动
3的宽度不设置,右浮动
4的宽度是200+border:2 一共202宽度,左浮动
然后再设置上传按钮,如果不设置样式,上传按钮是这样的

这样显然是老套的样式了,在网上找了一个解决方案是这样的

配合这样的样式

就可以做出这个效果了

所以html的代码如下:
   <style>
body{padding:10px}
/* 上传控件 */
.upload
{
    margin-top:10px;
    width:280px;
    height:30px;
}
.upload .uploadbtnBox
{
    float:left;
    height:30px;
    width:70px;
    margin-right:8px;
}
.upload .progress
{
    height:4px;
    line-height:4px;
    *zoom:;
    background:#fff;
    float:left;
    width:200px;
    border:1px #ccc solid;
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
    display:none;
}
.upload .filestate
{
    float:left;
    height:20px;
    text-align:left;
    width:150px;
    line-height:20px;
    display:none;
    color:#;
    overflow:hidden;
}
.upload .progresspercent
{
    float:right;
    padding-top:5px;
    height:15px;
    text-align:right;
    font-size:9px;
    line-height:15px;
    color:#;
}
.upload .uploadbtnBox .a-upload {
    height:28px;
    background:#4090c0;
    border:1px solid #dddddd;color:#ffffff;
    line-height:28px;
    padding: 6px;
    font-size:.9em;
    overflow: hidden;
    display: inline-block;
    text-decoration:none;
    *display: inline;
    *zoom:
}
.upload .uploadbtnBox .a-upload  input {
    position: absolute;
    width:70px;
    height:30px;
    overflow:hidden;
    margin-left:-10px;
    opacity: ;
    filter: alpha(opacity=);
    cursor: pointer
}
.upload .progress .bar
{
    height:4px;
    line-height:4px;
    background:#4090c0;
    *zoom:;
}
.clearfix:after {
    content: ".";
    display: block;
    height: ;
    visibility: hidden;
    clear: both;
}
.clearfix {
    _zoom: ;
}
.clearfix {
*zoom:;
}
    </style>
<div class="upload clearfix">
        <div class="uploadbtnBox clearfix">
            <a href="javascript:;" class="a-upload">
                <input type="file" data-url="uploadHandler.ashx" name="files" value="" id="file7"
                    onchange="CheckFile(this)" />点击上传 </a>
        </div>
        <div class="filestate">
            文件名</div>
        <div class="progresspercent">
        </div>
        <div class="progress" style="height: 4px;">
            <div class="bar" style="width: 0%;">
            </div>
        </div>
    </div>
JS部分
基本的upload直接这样就可以了,
$("input[type=file]").fileupload();
上传的后台页面通过input的data-url来设置,如下图

接下来要处理的是上传进度
通过计算上传的百分比设置bar的宽度就可以了
这里用到的是内置的progressall的方法,传递2个参数,第一个是e就是sender,通过他找到触发的input,然后再用jquery去找其他的兄弟元素进行操作,这里是找到了progress和bar然后设置他们的宽度
第二个参数是data,里面包含两个内置的变量,一个是total,一个是loaded,所以就可以计算出百分比了

上传完成后显示文件名,还有给隐藏input赋值,
使用的是内置的函数done,done会提供2个参数,第一个是e就是sender,我们通过他找到对应的input,然后找到其他元素进行操作
另一个参数就是result,在注释里已经说明了result如何使用了

所以最后的js就是这样
    <script type="text/javascript">
        function CheckFile(obj) {
            var array = new Array('gif', 'jpeg', 'png', 'jpg');  //可以上传的文件类型
            if (obj.value == '') {
                alert("让选择要上传的图片!");
                return false;
            }
            else {
                var fileContentType = obj.value.match(/^(.*)(\.)(.{1,8})$/)[3]; //这个文件类型正则很有用:)
                var isExists = false;
                for (var i in array) {
                    if (fileContentType.toLowerCase() == array[i].toLowerCase()) {
                        isExists = true;
                        return true;
                    }
                }
                if (isExists == false) {
                    obj.value = null;
                    alert("上传图片类型不正确!");
                    return false;
                }
                return false;
            }
        }
        $(function () {
            $("input[type=file]").fileupload({
                done: function (e, result) {
                    //done方法就是上传完毕的回调函数,其他回调函数可以自行查看api
                    //注意result要和jquery的ajax的data参数区分,这个对象包含了整个请求信息
                    //返回的数据在result.result中,假设我们服务器返回了一个json对象
            //但是由于IE10以下存在bug,会将XHR的内容识别错误,所以第一需要返回Content-Type: text/plain
            //其次,及时转成text/plain还存在取不到result.result的内容,取到的是其他的东西
            //需要用这个方法来接值,var jmsg = result.result[0].body ? result.result[0].body.innerHTML : result.result;
            //最后接到值后,发现还有<pre></pre>包着需要通过字符串处理去掉这个东西
                    //json对象{"newName": "sss", "oldName": "sdf"}
var resultJson;
	var jmsg = result.result[0].body ? result.result[0].body.innerHTML : result.result;
	var startIndex = jmsg.indexOf("{");
	var lastIndex = jmsg.lastIndexOf("}");
	jmsg = jmsg.substring(startIndex, lastIndex+1);
	try { resultJson = $.parseJSON(jmsg); }
	catch (e) { resultJson = jmsg; }
	var uploadDiv = $(e.target).parent().parent().parent();
	uploadDiv.find(".filehidden").val(resultJson.newName);
	uploadDiv.find(".filestate").show().text(resultJson.oldName);
                },
                progressall: function (e, data) {
                    var maxWidth = 200;
                    var percent = (data.loaded / data.total * 100).toFixed(2);
                    var progress = parseInt(data.loaded / data.total * maxWidth, 10);
                    var uploadDiv = $(e.target).parent().parent().parent();
                    uploadDiv.find(".progress").show();
                    uploadDiv.find(".bar").css("width", progress);
                    uploadDiv.find(".progresspercent").show().text(percent + "%");
                }
            })
        });
    </script>
ps:
但是由于IE10以下存在bug,会将XHR的内容识别错误,所以第一需要返回Content-Type: text/plain
其次,及时转成text/plain还存在取不到result.result的内容,取到的是其他的东西
需要用这个方法来接值,var jmsg = result.result[0].body ? result.result[0].body.innerHTML : result.result;
最后接到值后,发现还有<pre></pre>包着需要通过字符串处理去掉这个东西
git地址:https://git.oschina.net/jangojing/jqueryfileuploadDemo.git
用jQuery File Upload做的上传控件demo,支持同页面多个上传按钮的更多相关文章
- jQuery File Upload跨域上传
		
最近在做一个一手粮互联网项目,方案为前后端分离,自己负责前端框架,采用了Requirejs+avalonjs+jquery三个框架完成. 前后端通过跨域实现接口调用,中间也发现了不少问题,尤其是在富文 ...
 - jquery文件上传控件 Uploadify
		
(转自 http://www.cnblogs.com/mofish/archive/2012/11/30/2796698.html) 基于jquery的文件上传控件,支持ajax无刷新上传,多个文件同 ...
 - jquery文件上传控件 Uploadify   可以和ajax交互
		
http://www.cnblogs.com/mofish/archive/2012/11/30/2796698.html 原网址 基于jquery的文件上传控件,支持ajax无刷新上传,多个文件同 ...
 - jquery文件上传控件 Uploadify(转)
		
原文:http://www.cnblogs.com/mofish/archive/2012/11/30/2796698.html 基于jquery的文件上传控件,支持ajax无刷新上传,多个文件同时上 ...
 - 百度 flash html5自切换 多文件异步上传控件webuploader基本用法
		
双核浏览器下在chrome内核中使用uploadify总有302问题,也不知道如何修复,之所以喜欢360浏览器是因为帮客户控制渲染内核: 若页面需默认用极速核,增加标签:<meta name=& ...
 - 对百度WebUploader开源上传控件的二次封装,精简前端代码(两句代码搞定上传)
		
前言 首先声明一下,我这个是对WebUploader开源上传控件的二次封装,底层还是WebUploader实现的,只是为了更简洁的使用他而已. 下面先介绍一下WebUploader 简介: WebUp ...
 - asp.net中遍历界面上所有控件进行属性设置
		
* 使用方法: * 前台页面调用方法,重置: protected void Reset_Click(object sender, EventArgs e) { ...
 - 定制jQuery File Upload为微博式单文件上传
		
日志未经声明,均为AlloVince原创.版权采用『 知识共享署名-非商业性使用 2.5 许可协议』进行许可. jQuery File Upload是一个非常优秀的上传组件,主要使用了XHR作为上传方 ...
 - jQuery File Upload 图片上传解决方案兼容IE6+
		
1.下载:https://github.com/blueimp/jQuery-File-Upload 2.命令: npm install bower install ================= ...
 
随机推荐
- MongoDB Shard部署及Tag的使用
			
Shard部署 准备测试环境 为准备数据文件夹 Cd /home/tiansign/fanr/mongodb/Shard mkdir configdb1 configdb2 configdb3 mk ...
 - eclipse 提示错误**cannot be resolved to a type
			
这是某个对象不能识别为类型,比如你写了个类,名字叫Hello,如果你调用它的时候不小心写成hello,或者helo,那么就会报这样的错误,很容易改正的,只要你细心一点
 - KVM 介绍(4):I/O 设备直接分配和 SR-IOV [KVM PCI/PCIe Pass-Through SR-IOV]
			
学习 KVM 的系列文章: (1)介绍和安装 (2)CPU 和 内存虚拟化 (3)I/O QEMU 全虚拟化和准虚拟化(Para-virtulizaiton) (4)I/O PCI/PCIe设备直接分 ...
 - AI (Adobe Illustrator)详细用法(三)
			
本文主要是介绍和色彩相关的用法. 一.路径外观设置 1.设置描边粗细 手动输入20px 下拉选择 鼠标选中数值,按向上或向下的箭头调整 在右边的描边菜单中修改 Note:按住shift键,然后上下箭头 ...
 - [转]ASP.NET MVC 3 Razor + jqGrid 示例
			
本文转自:http://www.cnblogs.com/think8848/archive/2011/07/15/2107828.html 前些天写了一篇有关jqGrid的文章,因为是公司项目的原因一 ...
 - Zookeeper 监视(Watches) 简介(转)
			
Zookeeper C API 的声明和描述在 include/zookeeper.h 中可以找到,另外大部分的 Zookeeper C API 常量.结构体声明也在 zookeeper.h 中,如果 ...
 - 分层开发之MySchool
			
No.1实现登陆功能,验证用户名和密码.从数据库里进行匹配,看是否有符合要求的数据. 在DAL层编写代码,返回值为布尔类型.方法参数为(student实体类对象),使用参数化SqlParameter类 ...
 - 今天在看UWP蓝牙的例子
			
private async void InitializeRfcommServer() { ListenButton.IsEnabled = false; DisconnectButton.IsEna ...
 - jmeter的http sample使用
			
1.jmeter最简单的http sample 使用 : 最简单的get请求, 输入服务器名称或者ip, 如果有路径则添加路径 ,带参数的添加具体的参数及values值 parameters 和 bo ...
 - 给ros安装arbotix simulator仿真环境
			
首先下载程序包.编译.安装. cd ~/catkin_ws/src git clone https://github.com/pirobot/rbx1.git cd rbx1 git checkout ...