圖片上傳是web項目常見的需求,我基於以前的博客的代碼(請戳:formData批量上傳的多種實現)裏的第三種方法實現多圖片的預覽、上傳,而且支持三種方式添加圖片到上傳列表:選擇圖片、複製粘貼圖片、鼠標拖拽圖片,同時支持從上傳列表中移除圖片(點擊「X」號)css
頁面操做html
後臺接參程序員
頁面操做,使用Ctrl C、 V 效果也同樣web
後臺接參ajax
頁面操做bootstrap
後臺接參瀏覽器
代碼與以前的博客變化不大,主要是將p標籤換成了img標籤而且調整好樣式,input加入了格式校驗,使用window.URL.createObjectURL進行圖片的預覽等等,更多細節請直接看對比以前的代碼與如今的代碼安全
注:項目用到了bootstrap、layer、thymeleaf,須要先引入相關文件服務器
cssapp
注意:樣式在父頁面引入
.nav-bar { border-top: 1px solid #9E9E9E; margin: 10px 0 20px; } .nav-bar-title { margin: -13px 0 0 35px; background-color: white; padding: 0 10px; float: left; color: #199ED8; } .images-remove { font-size: 25px; color: red; cursor: pointer; position: relative; right: 0px; top: -15px; } .images-text-img { float: left; height: 100px; width: 100px; border: 1px solid #c2cad8; margin-bottom: 5px; } .images-text-img + i { float: left; line-height: 30px !important; } .input-images { width: 90% !important; padding: 4px 12px !important; } .images-list { border: 1px solid #c2cad8; padding: 10px; width: 400px; height: 355px; overflow: auto; }
imagesUpLoad.html
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <body> <div th:fragment="imagesPage(applyId)"> <div class="nav-bar"><span class="nav-bar-title">圖片上傳</span></div> <form th:applyId="${applyId}" class="form-horizontal images-form" enctype="multipart/form-data"> <div class='form-body'> <div class='form-group'> <div class="col-md-4"> <button type="button" class="btn btn-default images-btn" onclick="Images.appendImagesInput(this)"> 選擇圖片 </button> </div> </div> <div class='form-group'> <div contenteditable class="images-list"> </div> </div> </div> </form> </div> </body> </html>
js
只需執行一次初始化函數便可
var Images = { //初始化 init:function(){ Images.removeImagesInputListener(); Images.pasteImagesListener(); }, //上傳圖片 upload: function (applyId) { //終止上傳 if (!applyId) { layer.msg('images applyid is null'); return; } //添加附件 var formData = new FormData(); $("form[applyId='" + applyId + "']").find("input[name='images']").each(function (index, element) { //上傳的時候,先看FileList,在看咱們自定義的filess if ($(element).val() || element.filess) { formData.append("images", element.files.length ? element.files[0] : element.filess); } }); //追加applyId到formData formData.append("applyId", applyId); //執行上傳 $.ajax({ url: ctx + "/upload", type: "post", data: formData, processData: false, contentType: false, success: function (data) { if (checkResult(data)) { console.log('圖片上傳成功:', data); } }, error: function (e) { console.log('圖片上傳失敗'); throw e; } }); }, //添加待上傳圖片 appendImagesInput: function (btn,file) { //先追加html,input限制文件類型 能夠直接寫全,或者accept="image/*" $(btn).parents('.images-form').find(".images-list").append("<div><input type=\"file\" name=\"images\" class=\"hidden\" accept=\"image/gif,image/jpeg,image/jpg,image/png,image/svg\"/></div>"); //最新追加的input var images = $(btn).parents('.images-form').find(".images-list").find("input[name='images']"); if(file){ var $input = images[images.length - 1]; /* 在 HTML 文檔中 ,<input type="file"> 標籤是瀏覽器向服務器發送選中文件的。該元素有一個 value 屬性,保存了用戶指定的文件的名稱, 爲安全起見,file-upload 元素的value 屬性是隻讀的,不容許程序員修改它的值,而且HTML value 屬性也會被忽略。
解決方法:咱們定義一個本身的屬性來存儲file,上傳的時候作處理 */ $input.filess = file; var img = $("<img class='images-text-img' src=\"\"/>"); img.attr("src", window.URL.createObjectURL(file)); $($input).parent("div").append(img).append("<i class=\"fa fa-times images-remove\"></i>"); }else { //綁定input的change事件,注意:當咱們點擊取消或×號時並不觸發,可是無所謂,咱們在upload方法進行過濾空的input就能夠了 images[images.length - 1].onchange = function () { var fileName = $(this).val(); if (fileName) { var img = $("<img class='images-text-img' src=\"\"/>"); img.attr("src", window.URL.createObjectURL(this.files[0])); $(this).parent("div").append(img).append("<i class=\"fa fa-times images-remove\"></i>"); } else { $(this).parent("div").remove(); } }; //觸發最新的input的click images[images.length - 1].click(); } }, //刪除待上傳圖片 removeImagesInputListener: function () { $("body").on("click", ".images-remove", function (even) { $(this).parent().remove(); }); }, //添加圖片監聽 pasteImagesListener: function () { //粘貼事件 document.addEventListener('paste', function (event) { if (event.clipboardData || event.originalEvent) { var clipboardData = (event.clipboardData || event.originalEvent.clipboardData); if (clipboardData.items) { paste("paste",clipboardData.items); } } }); //拖拽事件 document.addEventListener("dragenter", function (e) { e.stopPropagation(); e.preventDefault(); }, false); document.addEventListener("dragleave", function (e) { e.stopPropagation(); e.preventDefault(); }, false); document.addEventListener("dragover", function (e) { e.stopPropagation(); e.preventDefault(); }, false); document.addEventListener("drop", function (e) { e.stopPropagation(); e.preventDefault(); paste("drop",e.dataTransfer.files); }, false); var paste = function (type,files) { var items = files, len = items.length, blob = []; for (var i = 0; i < len; i++) { if (items[i].type.indexOf("image") !== -1) { //兩種方式 if(type === "paste"){ blob.push(items[i].getAsFile()); }else if(type === "drop"){ blob.push(items[i]); } } } if (blob.length !== 0) { for (var i = 0; i < blob.length; i++) { Images.appendImagesInput($(".images-btn"),blob[i]) } } } } }; //調用初始化 Images.init();
controller
/** * 批量上傳 */ @PostMapping("upload") public ResultModel<List<AttachmentVo>> upload(MultipartFile[] images, @RequestParam("applyId") String applyId) { System.out.println(images.length); System.out.println(applyId); return null; }
父頁面調用
直接在須要上傳組件的地方嵌入
<div th:replace="attachment/imagesUpLoad::imagesPage(123456)"></div>
調用上傳方法
直接在瀏覽器的控制檯調用
Images.upload("123456");
還有一點不夠完美的就是當個人頁面出現多個上傳組件時(狀況參考以前博客了的新需求),經過複製粘貼、鼠標拖拽的方式時,調用Images.appendImagesInput追加html很差追加(目前是經過class去找),由於很差找到DOM對象,這裏先暫時知足頁面只有一個上傳組件的狀況,後面再進行升級