使用 FileReader 仅显示 div 网格中的最后一个图像,javascript,html,image,input,filereader"/>

首页 > 解决方案 > 循环使用 FileReader 仅显示 div 网格中的最后一个图像

问题描述

我正在尝试创建一个 HTML 表单,允许用户上传最多 5 张图片。在用户选择图像(从文件系统中使用<input multiple>)后,我想将它们显示在 5 个 div 中(ID 从 #contactImage0 到 #contactImage4)。

为了实现这一点,我使用 vanilla JS 循环选择的图像并将它们设置为相应 div 中的背景图像。问题是只有选择中的最后一张图像才会真正显示出来。所有其他 div 保持为空。

在调试了一下之后,我发现除了最后一个图像之外的所有图像都reader.result返回“”,但我无法弄清楚为什么我传递给的“图像”变量reader.readAsDataURL()似乎是有效的。

为什么会这样,我该如何解决?

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;
}

标签: javascripthtmlimageinputfilereader

解决方案


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

解决方案 1 - 创建一个新函数 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);
  }
}

解决方案 2 - 在 for 循环中使用另一个闭包

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);
    }
  })();
}

推荐阅读