简体   繁体   中英

Javascript onload event not firing inside object

I'm trying to get my head around why this doesn't work and wondered if someone could help me out. Basically I need multiple instances of this object with different images and I need each object to store the image height/width for its associated image for further operations, however the onload event never fires?

Sorry guys to be clear heres the complete code, if you see the TestTheVar function imgW is never set to anything.

<script type="text/javascript">

  (function() {

  var myTest = new TestObj();
  mytest.TestTheVar();
  })();

function TestObj() {
  this.img = new Image();

  this.img.onload = function(){
    this.imgW = this.img.width;
    this.imgH = this.img.height;
  };

  this.img.src = "reel_normal.PNG";
  this.TestTheVar = function() {
    alert(this.imgW);
  }

}
</script>

this is a keyword that belongs to each function.

In the load event listener it will be the image, not your TestObj instance.

Therefore, you can

  • Use this.img.imgW to get it:

     function TestObj() { var that = this; this.img = new Image(); this.img.onload = function(){ this.imgW = this.width; this.imgH = this.height; that.testTheVar(); }; this.img.src = "reel_normal.PNG"; this.testTheVar = function() { alert(this.img.imgW); }; } 
  • Store it in your TestObj instance:

     function TestObj() { var that = this; this.img = new Image(); this.img.onload = function(){ that.imgW = this.width; that.imgH = this.height; that.testTheVar(); }; this.img.src = "reel_normal.PNG"; this.testTheVar = function() { alert(this.imgW); }; } 
  • Customize this inside the event handler to be your TestObj instance:

     function TestObj() { this.img = new Image(); this.img.onload = (function(){ this.imgW = this.img.width; this.imgH = this.img.height; this.testTheVar(); }).bind(this); this.img.src = "reel_normal.PNG"; this.testTheVar = function() { alert(this.imgW); }; } 

You have two problems here

1) scope

2) timing

Scope, as mentioned in other answers refers to the fact that this inside the onload function is the Image object and not your TestObj so you would need to do the following:

<script type="text/javascript">

(function() {

    var myTest = new TestObj();
    mytest.TestTheVar();
})();

function TestObj() {
  var self = this;
  this.img = new Image();

  this.img.onload = function(){
    self.imgW = this.width;
    self.imgH = this.height;
  };

  this.img.src = "reel_normal.PNG";

  this.TestTheVar = function() {
    alert(this.imgW);
  }

}
</script>

Timing refers to the fact that you cannot assume the image has finished loading by the time you are trying to access height and width. This is what callbacks are good for:

<script type="text/javascript">

  (function() {

      var myTest = new TestObj(function() {
          myTest.TestTheVar();
      });

  })();

function TestObj(cb) {
  cb = cb || function() {};
  var self = this;
  this.img = new Image();

  this.img.onload = function(){
    self.imgW = this.width;
    self.imgH = this.height;
    cb();
  };

  this.img.src = "reel_normal.PNG";

  this.TestTheVar = function() {
    alert(this.imgW);
  }

}
</script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM