I need to adjust image sizes in a lazy loading mechanism. The final image paths are stored in attribute data-src, if lazy loading is enabled. For optical reasons, I don't want to wait until lazy loading is done, so I've tried the following:
window.addEventListener('load', function() {
const aImages = document.getElementsByClassName('article-image');
for ( var i=0;i<aImages.length;i++ ) {
const wrp = aImages[i].parentElement;
var imgHeight, imgWidth;
// if lazyload
if ( aImages[i].getAttribute('data-src') ) {
var img = new Image();
img.onload = function() { imgHeight = this.naturalHeight; imgWidth = this.naturalWidth };
img.src = aImages[i].getAttribute('data-src');
} else {
imgHeight = aImages[i].naturalHeight;
imgWidth = aImages[i].naturalWidth;
}
var dim = calcAspectRatioFit(imgWidth, imgHeight, wrp.clientWidth, wrp.clientHeight);
console.log('['+i+']\n' + 'dim.width: '+dim.width + '\ndim.height: '+dim.height + '\ntypeof(wrp): '+typeof(wrp) + '\nwrp.clientWidth: '+wrp.clientWidth + '\nwrp.clientHeight: '+wrp.clientHeight + '\nimgWidth: '+imgWidth + '\nimgHeight: '+imgHeight);
aImages[i].style.setProperty('width', dim.width + 'px', 'important');
aImages[i].style.setProperty('height', dim.height + 'px', 'imoprtant');
}
});
Guess the problem is the onload-function. If I set a breakpoint between it and before calcAspectRatioFit(), everything works as excepted. Guess 'img' then has enough time to load.
Debug-Output from console.log():
[0]
dim.width: NaN
dim.height: NaN
typeof(wrp): object
wrp.clientWidth: 222
wrp.clientHeight: 192
imgWidth: undefined
imgHeight: undefined
Any ideas how to solve this?
// Edit 2:
Of course, the problem was, that the last four lines didn't wait for img.onload() to be executed. Thanks @Peter Krebs for this hint. Here is a QnD solution which works fine. (Added anonymous wrapper fnc to copy i)
window.addEventListener('load', function() {
const aImages = document.getElementsByClassName('article-image');
const exec = function(i) {
const wrp = aImages[i].parentElement;
var dim = calcAspectRatioFit(aImages[i].naturalWidth, aImages[i].naturalHeight, wrp.clientWidth, wrp.clientHeight);
aImages[i].style.setProperty('width', dim.width + 'px');
aImages[i].style.setProperty('height', dim.height + 'px');
}
for ( var i=0;i<aImages.length;i++ ) {
if ( aImages[i].getAttribute('data-src') ) {
aImages[i].onload = (function(i) { return function() { exec(i) } })(i);
this.src = aImages[i].getAttribute('data-src');
} else { exec(i) }
}
});