前台HTML

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體:   |    |    |  超大  

需求有这么一个需求,一个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,然后写入如下代码,用于保存。

publicvoidPRocessRequest(HttpContext context)

{

context.Response.ContentType="text/plain";

context.Response.Charset="utf-8";

HttpPostedFile file= context.Request.Files["files"];stringuploadPath =HttpContext.Current.Server.MapPath(@context.Request["folder"]) +"\\";if(file !=null)

{if(!Directory.Exists(uploadPath))

{

Directory.CreateDirectory(uploadPath);

}

file.SaveAs(uploadPath+file.FileName);//下面这句代码缺少的话,上传成功后上传队列的显示不会自动消失stringnewName =file.FileName;stringoldName =file.FileName;

context.Response.Write("{\"newName\": \""+ newName +"\", \"oldName\": \""+ oldName +"\"}");

}else{

context.Response.Write("0");

}

}

前台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: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:06px;

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>

<divclass="upload clearfix">

<divclass="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>

<divclass="filestate">文件名</div>

<divclass="progresspercent">

</div>

<divclass="progress"style="height: 4px;">

<divclass="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">functionCheckFile(obj) {vararray =newArray('gif', 'jpeg', 'png', 'jpg');//可以上传的文件类型if(obj.value == '') {

alert("让选择要上传的图片!");returnfalse;

}else{varfileContentType = obj.value.match(/^(.*)(\.)(.{1,8})$/)[3];//这个文件类型正则很有用:)varisExists =false;for(variinarray) {if(fileContentType.toLowerCase() ==array[i].toLowerCase()) {

isExists=true;returntrue;

}

}if(isExists ==false) {

obj.value=null;

alert("上传图片类型不正确!");returnfalse;

}returnfalse;

}

}

$(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) {varmaxWidth = 200;varpercent = (data.loaded / data.total * 100).toFixed(2);varprogress = parseInt(data.loaded / data.total * maxWidth, 10);varuploadDiv =$(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

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航