需求场景: 用一个input type="file"按钮上传多张图片,可多次上传,可单独删除,最后使用ajax模拟form表单提交功能提交到指定方法中:
问题:由于只有一个file上传按钮,在多次点击上传按钮时,新的files文件会覆盖旧的files文件,需要使用一个变量集合存储;
单个文件的删除,也需要我们对这个集合进行修改,最后使用ajax模拟form表单提交功能。
html:
<section class="order-categories clearfix"> <div class="order-complaint-title">Order NO. $!{ORDER_ID}</div> <input type="hidden" value="$!{ORDER_ID}" name="OrderID" /> <textarea class="complaint-text" id="textareaContent" name="Content" placeholder="What is your Complaint?(At least 20 characters)"></textarea> <ul class="upimg-outer clearfix"> <li class="add"> <div> <span class="icon"></span> <input id="upFile1" type="file" name="file" value="" multiple="multiple" accept="image/*"> </div> </li> </ul> <input type="button" name="" id="btnSubmit" value="SUBMIT" class="order-complaint-btn"> </section>
JS:
图片上传&删除方法:
uploadImgObjectCss.prototype = { init: function () { var _this = this; _this.removeImg(); _this.upFileEleChange(); }, upFileEleChange: function () { var _this = this; _this.upFileEle.bind("change", function () { _this.setImagePreview(); _this.removeImg(); }); }, //图像数据收集及预览--最多上传4张 setImagePreview: function () { var _this = this; var docObj = _this.upFileEle[0]; for (i = 0; i < 4; i++) { var imgObjPreview = new Image(); if (docObj.files && docObj.files[i]) { imgObjPreview.src = window.URL.createObjectURL(docObj.files[i]); if (_this.upimgOuter.children("li:not(.add)").size() <= 3) { //判断files是否存在相同的图片 var isExist = false; for (var f = 0; f < _this.files.length; f++) { if (_this.files[f].name == docObj.files[i].name) { isExist = true; } } if (!isExist) { _this.upimgOuter.find(".add").before($("<li><i></i></li>").append($("<div></div>").append($(imgObjPreview)))); _this.files.push(docObj.files[i]); } } }; }; if (_this.upimgOuter.children("li:not(.add)").size() >= 4) { _this.upimgOuter.find(".add").hide(); }; }, //删除图片 removeImg: function () { var _this = this; var $revPhotoI = $(".upimg-outer li i"); $revPhotoI.bind("click", function () { var index = _this.upimgOuter.find("i").index(this); if (index > -1) { _this.files.splice(index, 1); //从files移除下标从index开始往下1个元素 $(this).parent("li").remove(); if (_this.upimgOuter.children("li:not(.add)").size() >= 4) { _this.upimgOuter.find(".add").hide(); } else { _this.upimgOuter.find(".add").show(); } } }); } }
提交方法:
var formData = new FormData(); formData.append("OrderID", _this.orderID); formData.append("Content", $(window.OrderComplaintCache.textareaContent).val()); for (var i = 0; i < _this.uploadImgObjectCss1.files.length; i++) { //formData.append("fileArray", _this.uploadImgObjectCss1.files[i]); formData.append("file" + i, _this.uploadImgObjectCss1.files[i]); } $.ajax({ type: "post", url: "/ajax/usercenterHandler.js?action=complaintorder", data: formData, processData: false, //必须 contentType: false, //必须 success: function (json) { var data = null; try { data = JSON.parse(json); } catch (e) { data = new Function("return " + json + "")(); } _this.fadeOutIconMessage("message-submit-succ", window.OrderComplaintCache.successMessage, 3000, function () { window.history.go(-1); }); }
这里要注意几点:
processData
设置为false
。因为data
值是FormData
对象,不需要对数据做处理。//<form>
标签添加enctype="multipart/form-data"
属性。//cache
设置为false
,上传文件不需要缓存。contentType
设置为false,不设置contentType值,
因为是由<form>
表单构造的FormData
对象,且已经声明了属性enctype="multipart/form-data"
,所以这里设置为false。
上传后,服务器端代码需要使用从查询参数名为file
获取文件输入流对象,因为<input>
中声明的是name="file"
。
重点1--FormData对象:
FormData对象是html5的一个对象,目前的一些主流的浏览器都已经兼容。额,如果你说ie8什么的,那我们还是来谈谈今天的天气吧,我没听见。呵呵,开个玩笑,不支持FormData的,可以使用方法二,下面会介绍。接着说FormData,它是一个html5的javascript对象,非常的强大。
FormData可以凭空创建一个对象,然后往这个对象里面添加数据,然后直接提交,不需要写一行html代码;
重点2--FormData添加多个上传文件:
a.多个文件使用同一个变量名:"fileArray";
formData.append("fileArray", _this.uploadImgObjectCss1.files[i]);
b.使用关键词"file"+数字: file0,file1...
formData.append("file" + i, _this.uploadImgObjectCss1.files[i]);
c.如果只有一个文件,除上面的方法外,可使用关键词"file"添加到FormData中