单按钮实现多附件上传(非异步,非flash,适用IE8)
最近接到一个web项目,其中的一个模块中要求下属单位向上级单位发送信息,信息里面也可包含用户上传的附件,附件个数不
定。对于这个项目,经理有严格界面要求,只有有一个按钮,而且样式一定按照页面风格来设计。由于我是才毕业的大学生,在编程
上还是个菜鸟,只用一个按钮实现多附件上传的功能还没有真正上手做过,于是去网上求助。google、百度出来的结果大都是用
jquery_ajax实现异步上传,或者是用已经做好的flash包。jquery_ajax异步上传使用起来很不方便,虽然是异步上传,但是如果用户已经
上传了附件,但后来又取消了这条信息的发送呢?又得去服务器和数据库里把那条信息对应的附件删除,很是麻烦,而且jquery_ajax异
步上传与flash包有一个很大的问题,很难控制他们的样式,必须要看懂、病修改成百上千行的jquery代码或者自己制作一个flash按钮。
后来由于
项目进度比较紧,不可能花时间来改jquery代码和学习flash(本人是菜鸟
),所幸就自己写了一个jquery的控件,故此来跟
大家分享
一下。
由于浏览器的安全设计,如果用button按钮绑定file标签的onclick()事件,在提交表单的时候flie标签的值会被清空,所以用常规方
法不能实现单按钮的多文件上传。那我们怎么办呢?规定是死的,但我们的脑子是活的,我想到如下的方法来解决这个问题:
当鼠标移动到“添加附件”按钮的时候,
将file标签覆盖到“添加附件“按钮之上,现在相信这些大家都有idea了,我们只需要给"添加附件"按钮绑定onmouseover()事件,当鼠
标移动到按钮上时候,创建一个file标签并覆盖在按钮之上,再把file标签设置为透明,用户点击的”添加附件“按钮,实际是点击的file
标签。
下面是我的例子:
fileUpload.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
<style type="text/css">
</style>
<script type="text/javascript" src="<%=basePath%>js/jquery.js"></script>
<script type="text/javascript" src="<%=basePath%>js/extraUpload_jquery.js"></script>
<script type="text/javascript">
$(function(){
moreFile($("#add"),$("#more"));
})
</script>
</head>
<body>
<form action="fileUpload" method="post" enctype="multipart/form-data">
<input type = "button" value="添加附件" id="add" />
<table border="1px" id="more">
<tr>
<td style="width:500px;text-align: center">附件名称</td><td style="width: 100px;text-align: center">操作</td>
</tr>
</table>
</form>
</body>
</html>
extraUpload_jquery.js
//单按钮实现多附件上传;
//上传的file标签:<input type="file" name="uploadFile"/> 用"uploadFile"再后退进行文件操作
//参数:btn(添加附件按钮jQurey对象,必须),
// table(附件列表jQuery对象,必须);
// img_url(删除附件按钮图片url,非必须,如果不传入则按照一般按钮处理);
//例子
// $(function(){
// moreFile($("#add"),$("#more"),"image/x1.jpg");
// });
//或者
// $(function(){
// moreFile($("#add"),$("#more"));
// });
function moreFile(btn,table,img_url){
//绑定添加附件按钮事件
btn.bind("mouseover",function(){
var n;
var file = $("<input type='file' name='uploadFile'/>");
//捕获按钮位置
var position = btn.offset().left;
//file标签覆盖添加附件按钮,并设置为透明
file.css({"position":"absolute","left":position-150,"filter":"Alpha(Opacity=0)"});
file.insertAfter(btn);
file.bind("change",function(){
var curr_FileName = file.val();
var trs = table.find("tr");
//验证文件是否已经上传
trs.each(function(i){
var old_FileName = trs[i].firstChild.innerHTML;
if(old_FileName==curr_FileName){
alert("已经存在名为'"+curr_FileName+"'的文件");
n=1;
return false;
}
});
if(n==1) return false;
//附件列表新增一行
var row = $("<tr/>");
var col_1 = $("<td/>").css("textAlign","center").appendTo(row);
var col_2 = $("<td/>").css("textAlign","center").appendTo(row);
col_1.html(file.val());
//方法重载
if(typeof(img_url)=="undefined"){
var deleteBtn = $("<input type='button' value='删除'/>").appendTo(col_2);
}else{
var deleteBtn = $("<img src="+img_url+">").appendTo(col_2);
}
row.appendTo(table);
deleteBtn.click(function(){
row.remove();
file.remove();
});
});
file.bind("mouseout",function(){
file.css("left",600);
});
});
}
在jsp中调用了extraUpload_jquery.js,和jquery包,注意它们之间的依赖关系和先后顺序。目前在IE8上测试没有任何问题,不知在firefox上表现如何,希望各位朋友多加指点。
另附extraUpload_jquery.js下载地址:点击打开链接