Saya mencoba membuat formulir HTML yang memungkinkan pengguna mengunggah hingga 5 gambar. Setelah pengguna memilih gambar (dari sistem file menggunakan <input multiple>) saya ingin menampilkannya dalam 5 div (diidentifikasi dari #contactImage0 hingga #contactImage4).

Untuk mencapai ini, saya mengulang gambar yang dipilih menggunakan Vanilla JS dan mengaturnya sebagai gambar latar di div yang sesuai. Masalahnya adalah hanya gambar terakhir dalam pilihan yang benar-benar muncul. Semua div lainnya tetap kosong.

Setelah men-debug sedikit saya menemukan bahwa untuk semua kecuali gambar terakhir reader.result mengembalikan "" tetapi saya tidak tahu mengapa karena variabel "gambar" yang saya berikan ke reader.readAsDataURL() tampaknya valid.

Mengapa demikian dan bagaimana cara memperbaikinya?

HTML:
<div id="contactImage0" class="imagePreview"></div>
<div id="contactImage1" class="imagePreview"></div>
<div id="contactImage2" class="imagePreview"></div>
<div id="contactImage3" class="imagePreview"></div>
<div id="contactImage4" class="imagePreview"></div>
<input id="upload" type="file" onchange="LoadImage(this)" name="image" accept="image/*" multiple>

JavaScript:
function LoadImage(input){

            if (input.files.length > 5){
                alert("You may only select a maximum of 5 images!");
                // TODO: Remove selected images
                return;
            }
            var i;
            for (i = 0; i < input.files.length; i++){
                var image = input.files[i]
                var imageDiv = 'contactImage' + i.toString();
                var element = document.getElementById(imageDiv);
                var reader = new FileReader();
                reader.onloadend = function(){
                    element.style.backgroundImage = "url(" + reader.result + ")"; // <-- RETURNS EMPTY STRING (EXCEPT FOR LAST IMAGE)        
                }
                if(image){
                    reader.readAsDataURL(image);
                    }else{
                    }
            }
        }

CSS (Shouldn't be the cause of the problem but you never know):
.imagePreview{
    margin: .5em;
    display: inline-block;
    width: calc(100% - 1em);
    height: 80px;
    background-color: #fff;
    background-image:url('');
    background-size:cover;
    background-position: center;
}
0
Frederik Hoeft 13 Agustus 2019, 13:57

1 menjawab

Jawaban Terbaik

Lihat https://dzone.com/articles/why -does-javascript-loop-only-use-last-value

Solusi 1 - Membuat fungsi baru setElementBackground

for (i = 0; i < input.files.length; i++) {
  setElementBackground(input.files[i], i);
}

function setElementBackground(file, i) {
  var image = file;
  var imageDiv = "contactImage" + i.toString();
  var element = document.getElementById(imageDiv);
  var reader = new FileReader();
  reader.onloadend = function() {
    element.style.backgroundImage = "url(" + reader.result + ")";
  };
  if (image) {
    reader.readAsDataURL(image);
  }
}

Solusi 2 - Menggunakan Penutupan Lain di dalam untuk loop

for (i = 0; i < input.files.length; i++) {
  (function() {
    var count = i;
    var image = input.files[count];
    var imageDiv = "contactImage" + count.toString();
    var element = document.getElementById(imageDiv);
    var reader = new FileReader();
    reader.onloadend = function() {
      element.style.backgroundImage = "url(" + reader.result + ")";
    };
    if (image) {
      reader.readAsDataURL(image);
    }
  })();
}
3
AKX 13 Agustus 2019, 11:19