你的位置:首页 > Java教程

[Java教程]用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("0");      }    }

 

 

前台HTML

预览效果

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

 

DIV结构

如上图

  1. 作为整个控件的最外层
  2. 是按钮
  3. 是上传完成后显示的文件名(上传开始前隐藏)
  4. 上传进度百分比(上传开始前隐藏)
  5. 上传进度条(上传开始前隐藏)

 

上图后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:1;  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:#333;  overflow:hidden;}.upload .progresspercent{  float:right;  padding-top:5px;  height:15px;  text-align:right;  font-size:9px;  line-height:15px;  color:#333;}.upload .uploadbtnBox .a-upload {  height:28px;  background:#4090c0;  border:1px solid #dddddd;color:#ffffff;  line-height:28px;  padding:0 6px;  font-size:0.9em;  overflow: hidden;  display: inline-block;  text-decoration:none;  *display: inline;  *zoom: 1}.upload .uploadbtnBox .a-upload input {  position: absolute;  width:70px;  height:30px;  overflow:hidden;  margin-left:-10px;  opacity: 0;  filter: alpha(opacity=0);  cursor: pointer}.upload .progress .bar{  height:4px;  line-height:4px;  background:#4090c0;  *zoom:1; }.clearfix:after {  content: ".";  display: block;  height: 0;  visibility: hidden;  clear: both;}.clearfix {  _zoom: 1;}.clearfix {*zoom:1;}  </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>

View Code

 

 

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对象          //json对象{"newName": "sss", "oldName": "sdf"}                    var resultJson = $.parseJSON(result.result)          $(e.target).attr("value", resultJson.newName);          var uploadDiv = $(e.target).parent().parent().parent();          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>

 

git地址:https://git.oschina.net/jangojing/jqueryfileuploadDemo.git