您的位置:首页 > Web前端 > HTML5

HTML5异步上传图片(支持预览和进度条),使用其他按钮触发file onclick事件,解决某些浏览器无法触发的问题

2015-11-09 19:31 1356 查看
很多情景下,都要求不要直接点击html的file标签,而是点击另外一个更加美观的图片,然后触发file标签的onclick事件打开系统的文件选择器。然而,某些低版本的浏览器为了安全,不支持onclick事件传递给file标签。百度搜索了半天,都是介绍把file标签透明化,然后覆盖再另外一个图片上面。可是这种非但比较复杂,还难以扩展和维护。

感谢万能的stackoverflow,终于在某个问题的某一个答案里面,说了一个很简单的解决方法:先file.focus,然后再用js触发file的click事件,然后再把file标签hide起来。具体代码如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link href="../resources/css/common.css" rel="stylesheet" />
<script src="../resources/js/jquery-1.11.3.js"></script>

<style type="text/css">
.addbtn img{width: 100px;}
.imgPreview{width:100px; height:100px; margin:10px;}
</style>

</head>

<body>
<h2>HTML5异步上传图片,带进度条</h2>
<form method="post" enctype="multipart/form-data">
其他需要提交的信息:<input type="text" name="otherInfo"/><br/><br/>

<a href="javascript:;" class="addbtn" id="addImgBtn">选择要上传的图片:<br/><img src="add-img.png" alt="选择并添加图片"></a>

</form>

<div id="imgPreview">
<br/>
<h3>图片预览:</h3> <!-- <img id="img" style="width:100;height:100"/> -->
</div>

<br/><br/>
<input type="button" value="开始上传" onclick="upload()"/>
<br/><br/>
上传进度:
<progress></progress><br/>
<p id="progress">0 bytes</p>
<p id="info"></p>
</body>

<script>
var totalSize = 0;

var fileNum = 0;

$(function(){
//绑定“选择并添加图片”按钮点击事件的callback
$("#addImgBtn").on("click", function(){
//新增一个file控件在“选择并添加图片”按钮前面
var fileHtml = '<input type="file" name="file" id=file' + fileNum + ' /accept="image/*">';
fileNum++;
$(this).before(fileHtml);

var fileControl = $(this).prev(); //获取新增的file控件对象

//为file控件绑定change事件的callback,图片被选择后会调用这个处理函数
//注意:一定要在click事件被传递给file控件之前绑定,否则有些低版本的浏览器无法支持
fileControl.on("change", function(){
//获取从文件选择器返回的信息:
var file = this.files[0]; //假设file标签没打开multiple属性,那么只取第一个文件就行了
name = file.name;
size = file.size;
type = file.type;
url = window.URL.createObjectURL(file); //获取本地文件的url,用于预览图片

//图片预览:
var imgHtml = '<img id="img'+ fileNum +'" class="imgPreview"/>';
imgHtml += "文件名:" + name + " 文件类型:" + type + " 文件大小:" + size /* + " url: " + url */ + "<br/>";
$("#imgPreview").append(imgHtml);
$("#img"+fileNum).attr("src", url);

//总计
totalSize += size;
$("#info").html("总大小: " + totalSize + "bytes");
});

//把点击事件传递给file控件
fileControl.focus(); //注意:某些浏览器,比如Android4.2版本的Webview,必须先focus file控件,不然无法弹出文件选择器!!!
fileControl.click();
fileControl.hide();
});
});

function upload() {
//创建FormData对象,初始化为form表单中的数据。需要添加其他数据可使用formData.append("property", "value");
var formData = new FormData($('form')[0]);

//ajax异步上传
$.ajax({
url: "http://localhost:8080/MyJavaStudio/servlet/file/upload",
type: "POST",
data: formData,
xhr: function(){ //获取ajaxSettings中的xhr对象,为它的upload属性绑定progress事件的处理函数

myXhr = $.ajaxSettings.xhr();
if(myXhr.upload){ //检查upload属性是否存在
//绑定progress事件的回调函数
myXhr.upload.addEventListener('progress',progressHandlingFunction, false);
}
return myXhr; //xhr对象返回给jQuery使用
},
success: function(result){
$("#result").html(result.data);
},
contentType: false, //必须false才会自动加上正确的Content-Type
processData: false //必须false才会避开jQuery对 formdata 的默认处理
});
}

//上传进度回调函数:
function progressHandlingFunction(e) {
if (e.lengthComputable) {
$('progress').attr({value : e.loaded, max : e.total}); //更新数据到进度条
var percent = e.loaded/e.total*100;
$('#progress').html(e.loaded + "/" + e.total+" bytes. " + percent.toFixed(2) + "%");
}
}
</script>

</html>


测试结果:



上传后保存的文件:



HTTP头信息和返回结果:





其他配置和后台接收文件代码,请参考:http://blog.csdn.net/clementad/article/details/49717397
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息