简体   繁体   中英

How to deal with occasionally wrong offsetWidths/Heights in IE11

Suppose we have the following:

var img = document.getElementById('someImageTag');
img.onload = function() {
  console.log(img.offsetWidth, img.offsetHeight);
};
img.src = "/path/to/300x200.png";

In IE11 (in both the edge and lower compatibility modes), I normally see 300, 200 in the console, as expected. But, I'm occasionally seeing 28 , 32 in the console (IE's "image not found" graphic?). Similarly, after the onload event of a descendent image fires, the offsetWidth and offsetHeight of the parent is usually -- but not always accurate.

The visible manifestation of this in our application is a transient bug wherein certain elements are being statically sized incorrectly. Some elements are intended to retain a particular size, as determined by the size of their children, when child elements are dragged out of them.

Is this a known issue? Is there a known workaround to get the same values? Or, are there more dependable values (that might not include borders/padding) that I should use?

Equally helpful, if not more helpful : Is there any way to consistently reproduce the problem [in a test], so I can determine when I've successfully worked around the issue?

You didn't mention which version of IE you were using, but I know that earlier versions of IE (6 and 7 at least) would sometimes do weird things when the image was cached.

I"m not in a position to test this, so give this a try:

function onloadHandler() {
  console.log(this.offsetWidth, this.offsetHeight);
}

var img = document.getElementById('someImageTag');
img.onload = onloadHandler;
img.src = "/path/to/300x200.png";

if( img.complete || img.readyState == "complete" ) {
  onloadHandler.call(img);
}

How to tell when an image is already in browser cache in IE9?

There are two ways I can think of to do this.

If you are looking to get the actual dimensions of the source image, you can make use of the naturalWidth and naturalHeight properties, which will return the values you are looking for when the offset is wrong.

img.onload = function() {
  //For browsers that don't support naturalWidth, use offsetWidth
  var myWidth = img.naturalWidth || img.offsetWidth,
      myHeight = img.naturalHeight || img.offsetHeight;
  console.log(myWidth, myHeight);
};


If you are looking for the adjusted size of the image from css/styling, I would recommend trying to delay the function with a timeout. It seems that IE11 will only return the incorrect values immediately after the onload event fires. Try something like this:

img.onload = function() {
  var myWidth = img.offsetWidth,
      myHeight = img.offsetHeight;

  //From my testing, the values IE11 returns aren't always 28 and 32
  if(myWidth < 40 && myHeight < 40){
    setTimeout( function(){
      console.log(img.offsetWidth, img.offsetHeight);
    }, 150); )
  }
};


If you expect to have images that are less than 40x40, the above if statement won't work. Assuming the element containing the img is larger than 40x40, you can check to see if the image is smaller than it's actual size with naturalWidth and naturalHeight. Try this:

img.onload = function() {
  var myWidth = img.offsetWidth,
      myHeight = img.offsetHeight,
      natWidth = img.naturalWidth || -1,
      natHeight = img.naturalHeight || -1;

  if( myWidth < 40 && myHeight < 40 && (myWidth < natWidth || myHeight < natHeight) ){
    setTimeout( function(){
      console.log(img.offsetWidth, img.offsetHeight);
    }, 150); )
  }
};

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