admin管理员组

文章数量:1417409

My class assignment wants me to use the defer tag for the script I am referencing, but this leads to the image's naturalWidth being undefined due to the order of execution in my js file.

My HTML has this line in the head (assignment wants me to put it in the <head> but use defer="defer") <script src="scripts/script.js" defer="defer"></script>

My js:

var catImageWidth = document.getElementById("cat-image").naturalWidth;
var birdImage = document.getElementById("bird-image");
birdImage.width = catImageWidth;

So I tried this:

var catImage = document.getElementById("cat-image");
var birdImage = document.getElementById("bird-image");
var catImageWidth;

catImage.onload = function() {
    catImageWidth = this.naturalWidth;
    console.log(catImageWidth) //logs 600
}

birdImage.width = catImageWidth; //logs `undefined`

I think that the assignment of birdImage.width is undefined because this line of code runs before catImage.onload actually happens. Does this mean that I'm slave to assigning birdImage.width within the scope of the function of catImage.onload?

P.S. I tried ES6 of catImage.onload = () => { //block of code } but this didn't seem to work.

My class assignment wants me to use the defer tag for the script I am referencing, but this leads to the image's naturalWidth being undefined due to the order of execution in my js file.

My HTML has this line in the head (assignment wants me to put it in the <head> but use defer="defer") <script src="scripts/script.js" defer="defer"></script>

My js:

var catImageWidth = document.getElementById("cat-image").naturalWidth;
var birdImage = document.getElementById("bird-image");
birdImage.width = catImageWidth;

So I tried this:

var catImage = document.getElementById("cat-image");
var birdImage = document.getElementById("bird-image");
var catImageWidth;

catImage.onload = function() {
    catImageWidth = this.naturalWidth;
    console.log(catImageWidth) //logs 600
}

birdImage.width = catImageWidth; //logs `undefined`

I think that the assignment of birdImage.width is undefined because this line of code runs before catImage.onload actually happens. Does this mean that I'm slave to assigning birdImage.width within the scope of the function of catImage.onload?

P.S. I tried ES6 of catImage.onload = () => { //block of code } but this didn't seem to work.

Share Improve this question edited Jun 11, 2017 at 3:19 simmonson asked Jun 11, 2017 at 3:09 simmonsonsimmonson 1372 silver badges10 bronze badges 0
Add a ment  | 

3 Answers 3

Reset to default 2

The issue is that you are trying to access a variable out of scope.

Please give this a try:

<img id="cat-image" src="https://static.pexels./photos/104827/cat-pet-animal-domestic-104827.jpeg">
<img id="bird-image" src="http://animalia-life.club/data_images/bird/bird3.jpg">

<script>
var catImage = document.getElementById("cat-image");
var birdImage = document.getElementById("bird-image");
var catImageWidth;

catImage.onload = function() {
    catImageWidth = this.naturalWidth;
    birdImage.width = catImageWidth;
}

console.log(birdImage.width);
</script>

Does this mean that I'm slave to assigning birdImage.width within the scope of the function of catImage.onload?

Seems so, that's the best way to do it.

You can use an arrow function, but not with the this keyword to reference the image.

Doesn't work:

catImage.onload = () => {
    catImageWidth = this.naturalWidth; //undefined
    console.log(catImageWidth)
}

Because in arrow function the this object doesn't bind to the image reference, it references the outer scope's this.

Does work:

catImage.onload = function() {
    catImageWidth = this.naturalWidth;
    console.log(catImageWidth) //logs 600
}

Or:

catImage.onload = function() {
    catImageWidth = catImage.naturalWidth;
    console.log(catImageWidth) //logs 600
}

This works as well, using JQuery (note that I save the element reference first (I am working with a JS class that maintains this element), then I need to properly get to the object that holds the naturalWidth within the onLoad function:

Get reference once DOM is built:

this._imageElement = $(this._htmlElement).find("img.theImage:first");
$(this._imageElement).on('load', this._onImageLoaded.bind(this));

The later:

_onImageLoaded() {
   this._imageWidth = this._imageElement[0].naturalWidth;
   this._imageHeight = this._imageElement[0].naturalHeight;
}

本文标签: javascriptWhy does naturalHeight or naturalWidth return undefinedStack Overflow