【问题标题】:Closure problem with image upload measurement图像上传测量的关闭问题
【发布时间】:2021-06-28 04:36:24
【问题描述】:

要在上传时检查上传的 img 的原始宽度和高度(然后相应地调整大小),我使用以下方法:

var reader = new FileReader();

//Initiate the JavaScript Image object.
var image = new Image(0,0);

//Read the contents of Image File.
reader.readAsDataURL(fileUpload.files[0]);
reader.onload = function () {

  //Set the Base64 string return from FileReader as source.
  image.src = this.result;

  //Validate the File Height and Width.
  image.onload = function () {

    var height = this.naturalHeight;
    var width = this.naturalWidth;
    if (height > 100 || width > 100) {

      // Do needed transformation      

    }
    
  };
};

好的,到目前为止一切顺利。但是现在,当我将其更改为多个文件上传的迭代时,如下所示:

for ( var i = 0; i < fileUpload.files.length; i++ ) {

  var reader = new FileReader();

  //Initiate the JavaScript Image object.
  var image = new Image(0,0);

  var iteratedFile = fileUpload.files[i];

  //Read the contents of Image File.
  reader.readAsDataURL(iteratedFile);
  reader.onload = function () {

    //Set the Base64 string return from FileReader as source.
    image.src = this.result;

    //Validate the File Height and Width.
    image.onload = function () {

      var height = this.naturalHeight;
      var width = this.naturalWidth;
      if (height > 100 || width > 100) {

        // Fails to do anything related to i; i is undefined here, returns undefined too 
        console.log( fileUpload.files[i] );

        // Returns the last iterated name
        console.log( iteratedFile );    

      }
    
    };
  };

}

我无法访问内部侦听器中的迭代文件。怎么会? 当我写console.log( iteratedFile ) 时,我实际上总是得到最后一个迭代文件的名称,这让我真正注意到这是一个闭包问题。但是,当我在同一个地方而不是那一行写console.log( i );console.log(fileUpload.files[i]) 时,我得到undefined,我不太明白。如何使 i / 迭代文件在最内部范围内可用(访问其名称、mime 等内容)?

更新

通过在reader.onload function的函数定义末尾添加(i);我现在可以在所有三个迭代的外部函数中控制台记录 i 的正确值,但随后会收到一个 GET 请求 404 错误发送到控制台中显示的pages_URL/undefined。什么?!

【问题讨论】:

    标签: javascript file upload closures onload


    【解决方案1】:

    i 的词法环境限定为在循环内调用的 IIFE 实际上足以让它像魅力一样工作:

    for ( var i = 0; i < fileUpload.files.length; i++ ) {
    
      (function(){
    
        var reader = new FileReader();
    
        //Initiate the JavaScript Image object.
        var image = new Image(0,0);
    
        var iteratedFile = fileUpload.files[i];
    
        //Read the contents of Image File.
        reader.readAsDataURL(iteratedFile);
        reader.onload = function () {
    
          //Set the Base64 string return from FileReader as source.
          image.src = this.result;
    
          //Validate the File Height and Width.
          image.onload = function () {
    
            var height = this.naturalHeight;
            var width = this.naturalWidth;
            if (height > 100 || width > 100) {
    
              // Works now
              console.log( fileUpload.files[i] );
    
              // Returns the iterated file
              console.log( iteratedFile );    
    
            }
        
          };
        };
    
      }());
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-21
      • 1970-01-01
      • 1970-01-01
      • 2019-04-26
      • 2017-06-22
      • 2020-05-13
      • 2012-01-01
      • 1970-01-01
      相关资源
      最近更新 更多