Есть массив картинок, которые отбираю по имени класса. Нужно их ресайзить в зависимости от соотношения ширина/высота. Но т.к. не все картинки загружены, когда выполняется скрипт, то img.width
возвращает 0. Пытаюсь добавить обработку картинок после загрузки, но не выходит - все равно возвращает 0. Где проблема?
function img_size() {
var array = document.getElementsByClassName('mob_img_select');
console.log(array);
for (var i = 0; i < array.length; i++) {
array[i].onload = onload_img(array[i]);
}
}
function onload_img(img) {
console.log(img);
if (img.width >= img.height) {
console.log('размер ' + img.width + 'x' + img.height);
img.className += ' mob_img_width';
}
else {
console.log('размер ' + img.width + 'x' + img.height);
img.className += ' mob_img_height';
}
}
img_size()
Соответственно, первые картинок 10 обрабатываются нормально и в консоли вижу
размер 210x210
А остальные выводит
размер 0x0
Если страницу перезагрузить, то все обрабатывается правильно, т.к. картинки уже в кеше.
Проблема №1 в том что Вы присваиваете свойству onload
не функцию, а результат ее выполнения.
Проблема №2 в том что пытаясь передать array[i]
параметром - не учитываете асинхронность вызова onload_image
. На момент выполнения этого обработчика, значение его аргумента img
может указывать не на тот элемент, который был в array[i]
при установке свойства onload
.
Это происходит потому, что цикл for
выполняется синхронно и не ожидает завершения обработчика - onload
будет вызвана браузером вне общего синхронного потока. Проще говоря, эта функция выполнится именно в момент события load
, которое возбудится после полной загрузки изображения.
Для того чтобы код заработал, как Вы ожидаете:
Строку
array[i].onload = onload_img(array[i]);
замените на
array[i].addEventListener('load', onload_img);
Далее, в обработчике onload_img()
замените:
img
на this
(и уберите аргумент обработчика)height
на naturalHeight
(если хотите получить высоту изображения, а не высоту элемента)width
на naturalWidth
(соответственно)document.addEventListener('DOMContentLoaded', img_size);
setTimeout(console.clear, 1e4);
function img_size() {
let array = document.getElementsByClassName('mob_img_select');
for (let i = 0; i < array.length; i++) {
array[i].dataset.idx = i;
array[i].addEventListener('load', onload_img);
}
}
function onload_img() {
let w = this.naturalWidth,
h = this.naturalHeight;
console.log(`размер изображения №${+this.dataset.idx + 1}: ${w}x${h}`);
if (w >= h)
this.classList.add('mob_img_width');
else
this.classList.add('mob_img_height');
}
<img class="mob_img_select" src="https://picsum.photos/400/280/?random">
<img class="mob_img_select" src="https://picsum.photos/160/300/?random">
<img class="mob_img_select" src="https://picsum.photos/100/65/?random">
<img class="mob_img_select" src="https://picsum.photos/200/200/?random">
<img class="mob_img_select" src="https://picsum.photos/200/370/?random">
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Привет, есть сайт, на котором работает калькулятор расчета стоимости за м2, нужно убрать соотношения сторон, но я не могу понять, где в коде...
У меня есть две ссылки на страницы, на одной из которых надо показать картинку, а на другой наоборот не показывать