Necesito ajustar los tamaños de imagen en un mecanismo de carga lenta. Las rutas de la imagen final se almacenan en el atributo data-src , si la carga diferida está habilitada. Por razones ópticas, no quiero esperar hasta que finalice la carga diferida, así que probé lo siguiente:
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');
}
});
Supongo que el problema es la función de carga. Si establezco un punto de interrupción entre él y antes de calcAspectRatioFit() , todo funciona como excepción. Supongo que 'img' tiene suficiente tiempo para cargar.
Salida de depuración de console.log():
[0]
dim.width: NaN
dim.height: NaN
typeof(wrp): object
wrp.clientWidth: 222
wrp.clientHeight: 192
imgWidth: undefined
imgHeight: undefined
¿Alguna idea de como resolver esto?
// Edición 2:
Por supuesto, el problema era que las últimas cuatro líneas no esperaron a que se ejecutara img.onload(). Gracias @Peter Krebs por esta sugerencia. Aquí hay una solución QnD que funciona bien. (Se agregó el envoltorio anónimo fnc para copiar 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) }
}
});