Reputation: 14282
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?
Upvotes: 3
Views: 2141
Reputation: 23
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); )
}
};
Upvotes: 0
Reputation: 23863
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?
Upvotes: 1