Earliest event to get image width

So, I have crappy JavaScript for centering images and <object> on the page if they exceed the threshold width. It also checks that some classes have not yet been applied manually.

 $('img,object').bind('load', function() { w = $(this).width(); if (w > 400 && !( $(this).hasClass('inlineimage') | $(this).parent().hasClass('inlineimage') )) $(this).css('margin', '10px ' + (parseInt((800-w)/2)-30) +'px'); }); 

This is terrible, but the meaning of this was initially quite normal. CMS does not make it easy to determine alignment and design it so that it takes a considerable amount of time from other tasks. It works on the client side.

The only problem with this is that JS waits for the whole image to load. Obviously, this means that on slower networks, the page loads, the images begin to load, and after a while the images snap. Ugly.

But the browser seems to know the width of the image as soon as it starts to download it. I would very much like to connect to this event and uncover this visual error.

Of course, if there is a way to approach CSS, I am also open to this.

+4
source share
3 answers

In browsers that support it, you can poll the natural sizes:

 var interval = setInterval( function() { if( img.naturalWidth ) { clearInterval(interval); console.log( "Natural available: "+ (new Date - now ); console.log( img.naturalWidth, img.naturalHeight ); } }, 0 ); 

In the demo here on an undisclosed image, I get:

 Natural available: 782 62 71 Loaded: 827 

Thus, real sizes were available 50 milliseconds before the boot event. Unfortunately, in IE, readistate "loading" does not guarantee real sizes.

Change the query string for the image before each test to make sure it is not locked.

Here is whatwg a reference to the actual sizes: http://www.whatwg.org/specs/web-apps/current-work/multipage/embedded-content-1.html#dom-img-naturalwidth

+2
source
 var span = document.getElementById('span'); // The parent span var check = function (){ if(span.offsetWidth > 0){ console.log('Width while loading', span.offsetWidth); } else{ setTimeout(check, 100); } }; check(); 

Demo This should show the width in the console at the first boot, and then the width after it loads. This is until the image is cached. (If the demo doesn’t work for someone, try changing the hoo part of the image url to something else)

+1
source

In the interest of this still working on more than the latest browsers, I put together all the efforts of speedy strength. He waits for 500 ms between attempts and checks the images to see if the current speed is skipped, like the last time he tried.

As soon as the image width is the same in two consecutive passes, we run the centering code.

This uses arrays to track things, so we do not constantly rape the DOM and do not request elements that are not applicable (because they have already been eliminated or eliminated).


 attempts = 0; arr = []; $.each($('img,object').not('inlineimage'), function(){ arr.push([this, -2, $(this).width()]); }); checkImgs = function() { attempts++; newarr = [] $.each(arr, function(){ if ($(this[0]).parent().hasClass('inlineimage')) return; w = $(this[0]).width(); this[1] = this[2]; this[2] = w; if (this[1] != this[2]) return newarr.push(this); // We know this image is loaded enough now - we can do things! if (w >= 400) $(this[0]).css('margin', '10px ' + (parseInt((800-w)/2)-30) +'px'); }); arr = newarr; if (arr.length && attempts < 6) setTimeout(checkImgs, 500); } setTimeout(checkImgs, 500); 

This is not very pretty, but it seems to work both efficiently (the processor clogged with some of my previous attempts) and quickly (cached spring images in place within 500 ms).

0
source

All Articles