需求場景: 用一個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中