多图片异步上传并实时预览
首先我的需求是这样的:
- 一个页面上需要上传很多图片
- 每张图片<1M
- 每张图片存到box中能预览,并直接ajax提交
这是我的页面:
一开始在网上找的一个前辈写的插件,一开始很欢喜啊,觉得很好用,但是并没有上传图片到后台的方法,然后找的另外的插件专门上传文件的,但是组合起来就是不行,各种问题,一气之下果断自己重新一点点写了。
首先整理一下思路:
- 点击当前的input[type=file],在写入value之后,要显示对应的按钮,并且点击对应预览按钮的时候要实时查看上传的图片
- 再次点击这个上传按钮的时候并传上图片之后点击预览要及时更新
- 每次value更新之后就上传到后台
- 在提交的时候会检测一次图片是不是都上传了,如果少那就当前行提示,一行的都上传完之后提示消失,我是在图片上传之后就加1,判断这个数值是不是对。
遇见的问题
- input[type=file]的change事件只能触发一次,所以决定在每次上传之前保存当前按钮的id和name值,上传之后删除当前的input并重新生成input,追加id和name;
- 注意新追加的input是未来元素,需要用事件委托给父级
- 所有的按钮操作要通过id来处理,不能通过class,这是坑
使用的知识点
- 实现图片的实时预览,就要把本地路径转化成base64格式,所以h5里面有个FileReader,可以获取到result,就是base64的值,相关参考
- 实现文件上传使用的是jquery-ajaxfileupload-js,动态创建iframe实现的 文件上传插件介绍
代码如下
//单个操作上传显示图片
function singleImg(inpO){
var count =0;
var thisId=$(inpO).attr("id");
var thisName=$(inpO).attr("name");
var nextp=$(inpO).next("p");
//console.info(count++);
//console.log("再次打印"+thisId);
var inpVnew=document.getElementById(thisId).value;
var lastS=inpVnew.lastIndexOf(".");
inpVnew=inpVnew.substr(lastS+1);
if(inpVnew == ''){
console.log("未选择任何图片");
return false;
}else if(inpVnew != 'jpeg' && inpVnew != 'jpg' && inpVnew != 'png' && inpVnew != 'gif') {
alert("图片类型必须是jpg,jpeg,pmg,gif中的一种");
return false;
}else{
//console.log(2);
var fileVal=document.getElementById(thisId).files[0];
var imgS = inpO.val();
//判断大小
var fileSize = fileVal.size;
//console.log(fileSize);
var maxSize = 1 * 1024 * 1024;
//限制图片最小大于0
if(fileSize > 0) {
if(fileSize > maxSize) {
alert('上传图片超出允许上传大小');
return false;
}
} else {
alert('上传图片必须大于0字节');
imgFlag=false;
return false;
}
//转换
var r = new FileReader();
r.readAsDataURL(fileVal); //Base64
//console.log(fileVal);
$(r).bind('load',function(){
var imgData = this.result; //base64数据
//console.log(imgData);
var haveHtml=nextp.html();
if(haveHtml == ''){
//追加
nextp.append('<img src="'+imgData+'"/>');
var img = nextp.children("img");
}else{
//更改
//imaData=showSrc;
var img = nextp.children("img");
img.prop("src",imgData);
}
if(img != '' || img != undefined){
var dataType = nextp.attr("data-type");
if(dataType=="zheng"){
nextp.parent("div").siblings(".idImgFC").show();
}else if(dataType=="fan"){
nextp.parent("div").siblings(".idImgBC").show();
}
}
uploadResource(inpO,nextp);
//lock =true;
$("input[name="+thisName+"]").prop("id",thisName);
//上传完之后循环判断是不是还提示
if($("#"+thisId).hasClass("js_upFile1")){
if($("#"+thisId).parents("li").find("img").length == '2'){
$("#"+thisId).parents("li").find(".popText").remove();
return false;
}
}else{
if($("#"+thisId).parents("li").find("img").length == '2'){
return false;
}else if($("#"+thisId).parents("li").find("img").length == '3'){
$("#"+thisId).parents("li").find(".popText").remove();
return false;
}else{
$("#"+thisId).parents("li").find(".popText").remove();
showText($("#"+thisId), '存在未上传的材料');
}
}
return imgNum++;
});
}
}
//上传方法
function uploadResource(obj,nextp) {
var id = $(obj).attr("id");
console.log(id);
var thisName=$(obj).attr("name");
var oP=$(obj).parent(".js_uploadBox");
//获取当前的下一个元素
//var nextP=$(obj).next("p");
//console.log(nextP.attr("id"));
//console.info(id);
$.ajaxFileUpload({
url : 'secure/uploadResource',
type : 'post',
data : {
"companyId" : $("#id").val()
},
secureuri : false, //一般设置为false
fileElementId : id, // 上传文件的id、name属性名
dataType : 'json', //返回值类型,一般设置为json、application/json
success : function(data, status) {
console.log(data);
//var res=eval(data);
//showSrc=res.data.url;
//删除当前元素,重新追加元素
//console.log($('#'+id));
$('#'+id).remove();
var newInp='<input type="file" class="js_upFile" data-new="new"/>';
nextp.before(newInp);
var nowInp=$('input[data-new="new"]');
nowInp.attr("id",id);
nowInp.attr("name",thisName);
nowInp.attr("accept","image/png,image/jpg,image/jpeg,image/gif");
//return showSrc;
},
error : function(data, status, e) {
obj.next("p").children("img").attr("src","");
alert(e);
}
});
};
//调用
$(".js_upFile").each(function(){
$(this).parent().on("change","#"+$(this).attr("id"),function(){
singleImg($(this));
})
});
结束语:整个过程相当的无奈,最后写完发现实际不难,很多都是第一次用,希望给你们一个参考思路