2013-05-07 38 views
9

的jsfiddle网址:http://jsfiddle.net/Xotic750/AjtLx使用readAsDataURL()用于图像预览

这方面的工作了一整天,我看不到的问题。这可能是由于我对FileReader对象的工作原理的狭隘理解,但我想要做的是使用readAsDataURL()获取用户选择的图像,并在屏幕上的表格中预览它们。一切都在努力减去......你猜对了......预览......很好。我认为我很近,因为预览会起作用,但它只显示该集合的最后一个图像。比如说,如果我上传了6张图像,那么第一行的3张图像就会被打破,第二行的第2张会被打破,然后最后的第6张图像会显示预览....任何建议非常感谢。此外,一旦这个作品它可能会帮助别人努力,因为我已经找遍了一个解决这个问题,我似乎无法挖什么后做同样的事情....

function PreviewImages() { 
    var inputID = document.getElementById('input_clone'); 
    var totalImages = inputID.files.length; 
    var imagesPerRow = 3; 
    var numRows = totalImages/imagesPerRow; 
    var row = ""; 
    var cell = ""; 
    var element1 = ""; 
    var elementID = ""; 


    for(var i = 0; i < numRows; i++){ //create rows 
     row = document.getElementById('image_preview_table').insertRow(i); 
     for(var ii = 0; ii < imagesPerRow; ii++){ //create cells 
      cell = row.insertCell(ii); 
      elementID = "img_" + ii; 
      element1 = document.createElement("img"); 
      element1.name = elementID; 
      element1.id = elementID 
      cell.appendChild(element1); 

      oFReader = new FileReader(); 

      oFReader.onload = function(oFREvent){ 
       var dataURI = oFREvent.target.result; 
       var image = document.getElementById(elementID); 
       image.src = dataURI; 
      }; 

       oFReader.readAsDataURL(document.getElementById("input_clone").files[ii]); 

    } 
} 
} 

回答

10

这里是一种解决方案,您可能会注意到,您的原创作了相当多的调整以使其起作用。

CSS

div.rounded { 
    width: 100%; 
    border-style: solid; 
    border-width: 1px; 
    border-radius: 5px; 
} 
label { 
    display: block; 
} 
input { 
    display: block; 
} 
#previewTable { 
    width: 100%; 
} 

HTML

<div id="imagesDiv" class="rounded"> 
    <label for="chooseFiles">Add Images</label> 
    <input type="file" id="chooseFiles" multiple="multiple" /> 
    <table id="previewTable"> 
     <thead id="columns"></thead> 
     <tbody id="previews"></tbody> 
    </table> 
</div> 

的Javascript

(function (global) { 
    var imagesPerRow = 3, 
     chooseFiles, 
     columns, 
     previews; 

    function PreviewImages() { 
     var row; 

     Array.prototype.forEach.call(chooseFiles.files, function (file, index) { 
      var cindex = index % imagesPerRow, 
       oFReader = new FileReader(), 
       cell, 
       image; 

      if (cindex === 0) { 
       row = previews.insertRow(Math.ceil(index/imagesPerRow)); 
      } 

      image = document.createElement("img"); 
      image.id = "img_" + index; 
      image.style.width = "100%"; 
      image.style.height = "auto"; 
      cell = row.insertCell(cindex); 
      cell.appendChild(image); 

      oFReader.addEventListener("load", function assignImageSrc(evt) { 
       image.src = evt.target.result; 
       this.removeEventListener("load", assignImageSrc); 
      }, false); 

      oFReader.readAsDataURL(file); 
     }); 
    } 

    global.addEventListener("load", function windowLoadHandler() { 
     global.removeEventListener("load", windowLoadHandler); 
     chooseFiles = document.getElementById("chooseFiles"); 
     columns = document.getElementById("columns"); 
     previews = document.getElementById("previews"); 

     var row = columns.insertRow(-1), 
      header, 
      i; 

     for (i = 0; i < imagesPerRow; i += 1) { 
      header = row.insertCell(-1); 
      header.style.width = (100/imagesPerRow) + "%"; 
     } 

     chooseFiles.addEventListener("change", PreviewImages, false); 
    }, false); 
}(window)); 

jsfiddle

+0

不错!似乎工作得很好,但在Firefox中遇到问题。 – commanderZiltoid 2013-05-08 03:13:04

+1

我自己看了看,发现了问题。第二个参数实际上在'removeEventListener'中不是可选的。 Chrome显然不抱怨,但Firefox。修改小提琴可以在http://jsfiddle.net/6cgTj/23/找到。 – 2013-05-08 03:59:38

+1

@Ray Nicholas,是的,这是Firefox的问题。我已更新,所有应该工作。 – Xotic750 2013-05-08 10:52:20

10

与您的代码的问题是:readAsDataURL()是异步的,您应该等到完成读取之后再调用第二次读取或通过调用新的FileReader()来创建新实例。

Xotic750的答案是有效的,因为他为每个图像创建一个FileReader,而只使用一个FileReader。因为FileReader.readAsDataURL()将整个图像转换为一个大字符串(以“data:image/jpeg; base64,/ 9j/4SVaRXhpZgAAS”的形式),所以使用FileReader预览图像并不是一个好的选择。 .....“),并且通过将整个图像数据串放入img.src属性来显示图像,如果图像很大,则会冒内存不足的风险。尽管您可以通过img.src =“data:image/jpeg;”指定包含整个图像数据的url,但是img.src是为了包含图像的url而不是图像的数据。 ...“。

所以,你应该用window.URL.createObjectURL()创建一个URL引用您的本地图片,并指定URL以便img.src:

... 
img.src = window.URL.createObjectURL(fileInput.files[i]); 
... 
+0

感谢您指出dataUrl和的疑难杂症,一直在努力与预览冻结UI加载中等大的图像(> 200kb) – 2017-12-02 05:37:52