【问题标题】:Multiple images preview are not showing多张图片预览未显示
【发布时间】:2014-08-21 06:45:27
【问题描述】:

此代码仅显示单个选定的图像。列表中选择的最后一张图像。我认为循环位置不正确或附加代码不正确。我也尝试过改变位置,但同样的事情只显示单个图像。

function readURL(input) {
  if (input.files && input.files[0]) {
    var reader = new FileReader(),
    count = input.files.length;
    for(i=0;i<=count;i++){
      reader.onload = function (e) {
        //$('.image_preview_cont').html('<img src="'+e.target.result+'" />');
        $('.image_preview_cont').append('<img src="#" id="img_preview'+i+'" />');
        $('#img_preview'+i).attr('src',e.target.result);
      }
      reader.readAsDataURL(input.files[i]);
    }
  }
}

HTML:

<tr>
    <td class="tdhead">Product Image</td><td><input type="file" name="p_image[]" 
    id="imgInp[]" multiple="true" onchange="readURL(this)" /><td>
</tr>
<tr>
    <td colspan="2"><div class="image_preview_cont"></div></td>
</tr>

【问题讨论】:

  • 在 reader.onload 函数中检查 i
  • reader.onload函数@Dart里面有两个"i"
  • 你不应该依赖 reader.onload 中的“i”,更好地计算 .image_preview_cont 中的 imgs,并使用此计数值而不是“i”。因为 reader.readAsDataURL 将异步执行(AFAIK)
  • 删除“i”也不会发生任何事情。你能建议用代码@Dart 回答吗
  • 这里是示例:jsfiddle.net/10r0kdex/2

标签: javascript html file-upload filereader


【解决方案1】:

您正在反复替换单个readeronload 处理程序,并且您不会在更改URI 之前等待加载一个图像。所以你只处理一张图像。

此外,当您的onload 处理程序开始执行时,i 很可能等于count,因为它是异步执行的,并且您将在您之后停止for 循环。 ve 到达了零索引数组的末尾。

加上a few console.log() statements,这一切都变得清晰了:

TypeError: Argument 1 of FileReader.readAsDataURL is not an object.
"Count: 3"
"readUrl: 0"
"readUrl: 1"
"readUrl: 2"
"readUrl: 3"
"onload: 3"

因此,显而易见的解决方法是不要做这些事情。首先,将您的负载处理程序创建为不依赖于for 循环中的i 的单独函数,然后您可以重用它:

function loadReader(e) {
    var i = $('.image_preview_cont img').length;
    $('.image_preview_cont').append('<img src="#" id="img_preview'+i+'" />');
    $('#img_preview'+i).attr('src',e.target.result);
}

然后,不要有一个FileReader,而是创建一个数组来容纳几个(每个图像一个):

var readers = [],
    count = input.files.length;

最后,修复for循环的终止条件,并在其中创建FileReader对象:

for(i=0;i<count;i++){
    readers[i] = new FileReader();
    readers[i].onload = loadReader;
    readers[i].readAsDataURL(input.files[i]);
}

Working fiddle.

【讨论】: