Страницы

Поиск по вопросам

суббота, 11 января 2020 г.

Массив картинок и обработка после их загрузки

#javascript


Есть массив картинок, которые отбираю по имени класса. Нужно их ресайзить в зависимости
от соотношения ширина/высота. Но т.к. не все картинки загружены, когда выполняется
скрипт, то 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



Проблема №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'); }

Комментариев нет:

Отправить комментарий