今天咱們聊一聊圖片上傳,單張Or多張 ,現在,各大圖片上傳插件數不勝數,例如:Jquery的 verupload.js,jQuery File Upload、Uploadify、jQuery.filter等等。But。上面說到的這些插件,今天咱們不談,咱們來看一看使用HTML5中的FileReader 如何實現 圖片的單張及多張預覽、刪除、上傳等功能。css
先看下實現後的效果以下:html
這塊是用戶點擊按鈕 其中咱們最重要的一句話是input type=file 和給了一個multiple屬性,能夠知足多張圖片上傳前端
<div class="form-group form-row"> <label class="col-sm-2 control-label uText">俱樂部相冊</label><div class="row"> <div class="col-xs-10 col-sm-8 mTop5"> <label title="上傳俱樂部相冊" for="ClubImagesUpload" id="btnClubImg" class="col-sm-2"> <input type="file" accept="image/*" name="ClubImagesUpload" id="ClubImagesUpload" class="hide" multiple="multiple"> <img src="/Images/registerNewSite/btn_addimg.png" class="addImg"/> </label> </div> </div></div>
下面這塊區域是用於圖片預覽的web
<div class="form-group form-row" id="preViewMore"><div class="row"> <div class="col-xs-9"> <div id="clubInputImagePreview" class="col-sm-9 img-preview img-preview-sm"></div> </div> </div></div>
什麼?連樣式你都要看,還有沒有人性(苦笑臉)數據庫
首先咱們分析下上面的html,咱們用一個label把input和一個img標籤包起來了,咱們但願點擊效果圖那個+號圖片,就能彈出選擇相片的對話框,因此,咱們須要先給label來一個點擊事件:後端
$("#btnClubImg").click(function() { //TODO Something });
接着咱們再看,由於咱們是要獲取上傳的文件,而咱們的文件主要是在input上,因此,咱們先將input標籤獲取到:瀏覽器
$("#btnClubImg").click(function() { var $input = $("#ClubImagesUpload"); console.log($input);//打印當前元素 });
咱們將當前input元素標籤打印出來看看是個什麼東東app
咱們展開第一項會發現files裏面length長度是0異步
好,咱們繼續分析,由於咱們想要能當input框改變的時候,說簡單點 就是有選擇到文件的時候,咱們能獲取到當前選擇的文件,這個和獲取input框文字輸入是同樣的道理,因此,通過分析,咱們知道須要給input標籤加一個change事件:ide
$("#btnClubImg").click(function() { var $input = $("#ClubImagesUpload"); console.log($input); $input.on("change", function () { console.log(this);//打印改變後的當前元素 }); });
讓咱們來瞄一眼,獲取到改變後的input元素裏面有些啥東東:
這裏很清楚得能夠看到,咱們獲取到了選擇的圖片,包括有最後修改事件,圖片名稱,大小以及圖片類型(有了文件類型,咱們就能夠判斷當前用戶選擇的是不是圖片不是嗎(斜眼笑))
一樣,這是單個文件的, 若是是多個文件,就會有多個file
接着往下看,經過打印輸出咱們能夠看到,咱們再input 標籤的files元素上已經拿到了咱們想要的文件信息,咱們只須要獲取它們就好了:
var files = this.files; var length = files.length;
這樣,咱們就能夠獲取到全部文件,以及文件的個數,那這裏問題來了,咱們若是是選擇多個文件,若是將其依次輸出並展現到頁面上呢?
看到上面標註的四個字,腦殼中有沒有閃現出兩個字呢?循環
$.each(files, function (key, value) { //TOTO Something });
經過將上面獲得的files 循環,咱們能夠依次獲得每一個文件的信息。這樣,你就不只能夠將其依次輸出,若是你願意,你還能夠將其送上天~
var fileReader = new FileReader();//實例化一個FileReader對象 var file_ = files[key];//獲取當前文件 if (/^image\/\w+$/.test(file_.type)) {//將當前文件進行正則匹配,看是不是選擇的圖片 fileReader.onload = function() {//當讀取操做完成時調用 } }
有必要延伸下FileReader的知識點:
FileReader主要用於將文件內容讀入內存,經過一系列異步接口,能夠在主線程中訪問本地文件。
使用FileReader對象,web應用程序能夠異步的讀取存儲在用戶計算機上的文件(或者原始數據緩衝)內容,可使用File對象或者Blob對象來指定所要處理的文件或數據。
回到主題,咱們已經可以獲得文件而且獲得返回,因此此時,咱們只須要展現返回的結果就好了
$("#clubInputImagePreview").css("background-image", "url(" + this.result + ")");
咱們將其this.result打印出來看看是個什麼東東:
不言而喻,是將圖片轉換成了Base64的數據格式。最後,咱們調用 readAsDataURL 讀取文件內容,將其用data:url字符串表示出來
fileReader.readAsDataURL(value);
這樣,你就能夠獲得一個簡易的圖片上傳的Demo了,可是並非最終的,由於你還須要加不少業務進去。好比:獲得一張預覽圖片後,當前標籤會被佔用,若是下次循環進來,直接使用原標籤,確定會將以前的圖片替換,那這確定不是咱們想要的效果,
咱們但願是能依次展現,而不是替換展現。因此,咱們還須要作一些處理:
$("#clubInputImagePreview").css("background-image", "url(" + this.result + ")"); //使用apend再當前元素下追加一個子節點 $("#clubInputImagePreview") .append("<img src='/Images/registerNewSite/btn_r_del.png' class='clubsImage' id='ImgRemove' />"); //使用after 向當前兄弟節點 追加一個同級節點 $("#clubInputImagePreview").after( "<div id='clubInputImagePreview1' class='col-sm-9 img-preview img-preview-sm delImg' ></div>");
而後咱們追加的刪除圖片,也須要給其點擊事件,讓咱們的當前預覽區域消失:
$("#ImgRemove").click(function () { $(this).parent().remove(); });
最後,你會發現結果還不是咱們想要的,那是由於 當前ID還在,因此沒法進行下一步操做,而咱們只須要將當前元素的Id Remove掉,而後新增一個同ID的元素,這樣瀏覽器就會認爲這是一個新的元素:
$input.removeAttr("id"); var newInput ='<input type="file" accept="image/*" name="ClubImagesUpload" id="ClubImagesUpload" class="hide" multiple="multiple">'; $(this).append($(newInput));
最後完整JS代碼以下:
var intP = 0; $("#btnClubImg").click(function() { var $input = $("#ClubImagesUpload"); // console.log($input); $input.on("change", function () { // console.log(this); var files = this.files; var length = files.length; if (intP > 8) { layer.msg('圖片不能再多了~', {}); return; } $.each(files, function (key, value) { var fileReader = new FileReader(); var file_ = files[key]; if (/^image\/\w+$/.test(file_.type)) { fileReader.onload = function() { if (intP > 8) { layer.msg('圖片不能再多了~', {}); return; } if (key == 0 && intP == 0) { console.log(this.result); $("#clubInputImagePreview").css("background-image", "url(" + this.result + ")"); $("#clubInputImagePreview") .append( "<img src='/Images/registerNewSite/btn_r_del.png' class='clubsImage' id='ImgRemove' />"); $("#clubInputImagePreview").after( "<div id='clubInputImagePreview1' class='col-sm-9 img-preview img-preview-sm delImg'></div>"); } else { $("#clubInputImagePreview" + parseInt(intP) + "").css("background-image", "url(" + this.result + ")"); $("#clubInputImagePreview" + parseInt(intP) + "").append( "<img src='/Images/registerNewSite/btn_r_del.png' class='clubsImage' id='ImgRemove" + parseInt(parseInt(1) + parseInt(intP)) +"' />"); $("#clubInputImagePreview" + parseInt(intP) + "").after( "<div id='clubInputImagePreview" + parseInt(parseInt(1) + parseInt(intP)) + "'class='col-sm-9 img-preview img-preview-sm delImg' ></div>"); } if (key == 0 && intP == 0) { $("#ImgRemove").click(function () { $(this).parent().remove(); }); } else { $("#ImgRemove" + parseInt(parseInt(1) + parseInt(intP)) + "").click(function () { $(this).parent().remove(); }); } intP += parseInt(1); }; fileReader.readAsDataURL(value); } else { layer.msg("格式錯誤<br/>請選擇一個圖片文件"); } }); }); $input.removeAttr("id"); var newInput = '<input type="file" accept="image/*" name="ClubImagesUpload" id="ClubImagesUpload" class="hide" multiple="multiple">'; $(this).append($(newInput)); });
下一篇,將講述 如何將前端獲得的多個File ,存入進數據庫,後端是.NET Core,敬請期待吧~