2011-05-28 42 views
1

我有一个工作版本的HTML5拖动& drop file uploader。我正在编辑JS代码以支持在同一页面上进行多个文件上传。通过尝试访问注册为事件的方法中的“实例”属性,我遇到了一个问题。JavaScript多个对象实例,无法正确访问事件处理程序中的属性

问题由下面的代码在方法this.drop中显示。 这个存在的原因。$$ upload_self属性是通过这个属性访问数据。例如,我不能使用这个关键字this.drop函数,因为当事件发生时,这个没有引用我的“实例”。

我不确定通过创建$$ upload_self是个不错的主意。

这样创建的新实例区域:

将&拖放文件的上传
var recording_upload = new upload(); 
    recording_upload.init(recording_upload, ...); 

代码:

var upload = function() { 
    this.$$upload_self = null; 
    this.$drop = null; 
    this.$status = null; 
    this.$progress = null; 
    this.maxNumberOfFiles = null; 
    ... 

    this.init = function (self, pUrl, maxNmbOfFiles, dropArea, progress, status) { 
     $$upload_self = self; 
     $$upload_self.postUrl = pUrl; 
     $$upload_self.maxNumberOfFiles = maxNmbOfFiles; 

     $$upload_self.$drop = $("#" + dropArea); 
     $$upload_self.$progress = $("#" + progress); 
     $$upload_self.$status = $("#" + status); 

     $$upload_self.$drop.bind('dragenter', $$upload_self.enter); 
     $$upload_self.$drop.bind('dragleave', $$upload_self.leave); 
     $$upload_self.$drop.bind('drop', $$upload_self.drop); 
    }; 

    this.enter = function (e) { 
     $(e.target).addClass('hover'); 
     return false; 
    }; 

    this.leave = function (e) { 
     $(e.target).removeClass('hover'); 
     return false; 
    }; 

    this.drop = function (e, _this) { 
     $(e.target).removeClass('hover'); 
     var files = e.originalEvent.dataTransfer.files; 

     if (files.length > $$upload_self.maxNumberOfFiles) { // for example, here $$upload_self references always last instance... 
      $$upload_self.displayErrorMessage('Error: You can only drop ' + $$upload_self.maxNumberOfFiles + ' file(s) at time.'); 
      return false; 
     } 
    ... 
    }; 
    ... 
} 

有任何解决方法来解决这个问题?我相信这可能是一个普遍的问题,但无法解决这个问题。

任何帮助,非常感谢。

回答

1

您可以完全关闭new关键字,并为每个实例upload使用全新关闭。

编辑:更新,以避免潜在的全球性this的破坏。

var upload = function(pUrl, maxNmbOfFiles, dropArea, progress, status) { 
    return { 
     postUrl: pUrl, 
     ... 
     drop: function(e) { 
      ... 
      if (files.length > this.maxNumberOfFiles) { 
       this.displayErrorMessage(...); 
      } 
      ... 
     }, 
     ... 
    }; 
}; 

... 

var someUpload = upload(...); 
1

尝试搜索“范围”。作为一个例子,看看它如何在ExtJS中实现。

+0

这不是一个范围问题;这是函数调用和'this'的语义问题。 – Pointy 2011-05-28 22:38:35

+0

这是ExtJS方面的“范围”。不是可变范围,但可能是一些背景 - 我不知道更正确的通用词。 – gaRex 2011-05-28 22:44:28

1

在现代浏览器,你可以这样做:

$$upload_self.$drop.bind('dragleave', $$upload_self.leave.bind($$upload_self)); 

对于老版本的IE,你可以这样做:

$$upload_self.$drop.bind('dragleave', function() { $$upload_self.leave(); }); 

真的是 “.bind()” 方法的所有函数对象的新的浏览器只是为你创建一个小的中间函数,基本上就像第二个例子。 Mozilla docs page for ".bind()"有一个非常好的代码块,您可以将它用作本地不支持“.bind()”的浏览器的“polyfill”补丁。

相关问题