如何确保FileReader使用Javascript

时间:2017-05-15 03:27:23

标签: javascript html5 dom file-upload filereader

我在XML文件中定义了各种HTML元素。 我无法将我的XML元素整体显示,但它有多行,每行包含复选框,文件上传选项等。

我使用Javascript获取这些元素然后使用XMLHTTPRequest,将这些请求发送到控制器进行处理。

想象一下HTML元素如下所示:

Row1 ----  Checkbox1_Row1   TextDescription_Row1     FileUpload_Row1    
Row2 ----  Checkbox1_Row2   TextDescription_Row2     FileUpload_Row2    

我可以拥有尽可能多的行。

使用Javascript,我得到所有这些表单元素,这些元素由行号(Row1,Row2)区分。

我循环遍历每个表单元素然后

for(var j=0; j< formelements.length; j+++)
{
  if (formElements[j].type == "textbox")
   {
        Do something
    }
    elseif (formElements[j].type == "file")
    {
        var Base64String;
        var ready = false;
        var fileName = formElements[j].files[0].name;

        var check = function () {
        if (ready === true) {               
         array.push(Base64String);                           
         return;
         }
         setTimeout(check, 1000);
         }

         check();

         var reader = new FileReader();
          reader.onloadend = function (evt) {
          Base64String = evt.target.result;
          ready = true;
          };
         reader.readAsDataURL(file);
        }
    }

我正在使用一个数组来推送对应于每一行的所有值,并且在进行一些更改后,具有最终值的数组将被发送到控制器。这里是文件上传选项,我从每行读取文件并将它们转换为二进制格式并发送到控制器。如果只有一行,这种方法可以正常工作。当有多行时,这种方法会发生什么,当循环遍历表单元素时,它会检查第一行(比如文本框)的所有内容并放入数组,但是当它是文件类型时,它会进入循环并读取文件。读取文件需要花费一些时间,并且时间循环将转到下一个表单元素(这只是Row2)。现在Row2表单元素进入图片说,我们不上传任何文件,它将为null。现在check()函数已完成,并且完全读取了row1中的文件。由于循环已经在第2行表单元素中,因此除了空值之外,此文件值将被分配给Row2。因此,当涉及到文件类型时,Row2将同时具有空值和文件值,但Row1没有值。类似地,如果我有多行中的多个文件,则根据FileReader读取的时间将文件值分配给当前循环中存在的行表单元素。

我需要确保在转到下一个表单元素之前完全读取文件值。怎么做到这一点?

************************更新**********************

这里提到的标记为重复的问题只有文件类型,因此,它们可以遍历文件类型。对我来说,表单元素由Checkbox1_Row1,TextDescription_Row1,FileUpload_Row1,Checkbox1_Row2,TextDescription_Row2,FileUpload_Row2组成。

我必须确保FileUpload_Row1从文件中读取了正确的值,然后再转到下一个表单元素,这里是Checkbox1_Row2。

1 个答案:

答案 0 :(得分:1)

{p> evtevent evt.target.result。当.push() event.target.result等于fileList

时,我需要fileList .lengthcount数组

<!DOCTYPE html>
<html>

<head>
  <script>
    function myFunction() {
      var files = Array.prototype.map.call(
        document.querySelectorAll("[id^=myFile]")
        , function(input) {
            return {id:input.dataset.id, file: input.files[0]};
      });

      var count = files.length; // total number of files
      var fileList = []; // accepted files

      for (var i = 0; i < count; i++) {
        var file = files[i].file;
        var id = files[i].id;
        var filename = files[i].file.name;
        if (i >= count) {
          break;
        }

        var reader = new FileReader();

        reader.onload = (function(id, filename) {
          return function(event) {
            fileList.push({id, filename, file:event.target.result}); {
              if (fileList.length === count) {
                // do stuff with `fileList`
                console.log(fileList);
              }
            }
          }
        })(id, filename);
        reader.readAsDataURL(file);
      }
    }
  </script>
</head>

<body>
  <h1>Hello Plunker!</h1>
  <input type="file" id="myFile_row1" data-id="A">
  <input type="file" id="myFile_row2" data-id="B">
  <input type="file" id="myFile_row3" data-id="C">

  <button onclick="myFunction()">Try it</button>

</body>

</html>

plnkr http://plnkr.co/edit/VCGPPbWcock0PgC9wMWi?p=preview