進度條

【實體課程】WordPress 跨界網站接案講座暨工作坊 | 開源研究室 x 進度條線上課程

開源研究室 x 進度條線上課程,台北場盲鳥票開賣中!! 至 11/08 (日) 23:50 為止喔!購票與詳情請看「KKTIX 購票頁面」或「進度條文章

[JavaScript] 上傳圖片同時預覽一張不夠,那你有試過兩張嗎?

上傳圖片同時預覽已經會了,但改成多張圖片好像就不會了。

作者: 縱裕 更新日期:

在之前的文章我們已經嘗試的玩過上傳圖片同時預覽

如果沒看過的讀者可以先看看上一篇

[JavaScript] 上傳圖片不難,那上傳同時預覽呢?

 

 

看過的同學也可以再點進去看,我們已經在最下面加入了Ruby On Rails的相關課程影片。所以你可以看到前端程式碼與後端連結的過程。

(當然你所熟悉的可能不是Ruby On Rails,不過其實大多數的程式框架都是用一樣的概念去實作。)

 

 

 

 

說真的,有在寫程式的工程師,找到上篇提到的Stackoverflow文章並不是難事。只要英文關鍵字有下對,多半就會是Google搜尋的第一或第二篇。因此在上一篇雖然有提到說這是同學詢問的問題,其實該問題完整應該是如何同時上傳且預覽多張圖片。這種功能在很多大量上架的網站類型其實滿常見的。

 

 

(本文完成截圖1,此文章下面可以直接試玩)

 

(本文完成截圖2,此文章下面可以直接試玩)

 

 

那我們先回顧一下上一篇的程式碼

我們以比較單純的jQuery & JavaScript混合版本為例

<!-- JavaScript & jQuery 版本-->
<!-- HTML part -->
<form action="/somewhere/to/upload" enctype="multipart/form-data">
   <input type="file" id="progressbarTWInput" accept="image/gif, image/jpeg, image/png"/ >
    <img id="preview_progressbarTW_img" src="#" />
</form>
<!-- JavaScript part -->
<script>
$("#progressbarTWInput").change(function(){
  readURL(this
);
});

function
readURL(input){
  if(input.files && input.files[0]){
    var
reader = new FileReader();
    reader.onload = function
(e) {
      $("#
preview_progressbarTW_img").attr('src', e.target.result);
    }
    reader.readAsDataURL(input.files[0]);
  }
}

</script>

 

首先,我們必須要開啟多選的功能。

這是HTML的功能,所以我們只要在<input type="file"> 加上multiple 這個屬性(attribute)

<input type="file" multiple />

或是在XHTML這個現在比較少見的格式中要用 multiple="multiple" 

就可以變成多選了

(XHTML現在看起來算是個過渡期的HTML版本,但很多以前開發的套件會幫你自動改成這個格式)

 

 

再來則是change event

這邊並不需要改,因為無論是選取一張或是選取兩張以上,

都是改變value,都會呼叫一樣的event,也都會傳<input>進來

 

 

因此其實重點就還是在 function readURL(input){...} 這個function 上面。

不過說難也沒多難,畢竟我們的if 裡面本來就有在確認他是否是為NULL,而且認為他是一個陣列(Array)。

看到陣列,就要想到迴圈,他們兩個同時出現的機會大概是90%,剩下的10%則是因為有人偷懶或是寫錯了。

所以我們可以把程式碼改成。

for(var i = 0; i < input.files.length; i ++){

   var reader = new FileReader();
   reader.onload = function (e) {

      <....這裡還有點問題>

   }

   reader.readAsDataURL(input.files[i]);

}

這樣每讀到一個file,我們都會驅動一次onload事件,一張圖都跑不掉。

 

 

不過這樣會有問題,因為我們原本使用id 去抓 <img> 然後再顯示。

但現在有很多張圖,無法顯示在同一張<img>上。

因此這裡提供一個簡單的方案,改成去抓一個<div>,然後動態的生出<img>。

 

 

因此程式碼會變成類似:

function readURL(input) {
  if (input.files && input.files.length >= 0) {
    for(var i = 0; i < input.files.length; i ++){
      var reader = new FileReader();
      reader.onload = function (e) {
        var img = $("<img width='200' height='150'>").attr('src', e.target.result);
         $('#images').append(img);
      }
      reader.readAsDataURL(input.files[i]);
     }
   }
 }

 

整個完成的程式碼則為:

 

 

<!-- HTML part -->
<form action="/somewhere/to/upload" enctype="multipart/form-data">
   <input type="file" id="progressbarTWInput" accept="image/gif, image/jpeg, image/png" multiple/ >
   <div id="preview_progressbarTW_imgs" style="width:100%; height: 300px; overflow:scroll;">
       <p>目前沒有圖片</p>
   </div>
</form>

<!-- JavaScript part -->
<script>
$("#progressbarTWInput").change(function(){
  $("#
preview_progressbarTW_imgs").html(""); // 清除預覽
  readURL(this
);
});


function readURL(input){
  if (input.files && input.files.length >= 0) {
    for(var i = 0; i < input.files.length; i ++){
      var reader = new FileReader();
      reader.onload = function (e) {
        var img = $("<img
width='300' height='200'>").attr('src', e.target.result);
        $("#
preview_progressbarTW_imgs").append(img);
      }
      reader.readAsDataURL(input.files[i]);
    }
  }else{
     var noPictures = $("<p>目前沒有圖片</p>");
     $("#
preview_progressbarTW_imgs").append(noPictures);
  }
}

</script>

 

 

       
       

目前沒有圖片

   

 

所以這個看似複雜的功能,其實只是很單純的迴圈的運用以及apped element(還有基本的上傳)。

最後,讓這個程式的外觀變好一點的工作就交給各位啦!!

 


最後,如果你喜歡我們的文章,別忘了到我們的FB粉絲團按讚喔!!

Medium picture

縱裕

錄課程錄到快死掉了啊!!!