Как определить, загружено ли изображение, используя Javascript / jQuery? - PullRequest
82 голосов
/ 04 ноября 2008

Я пишу некоторый Javascript, чтобы изменить размер большого изображения, чтобы оно поместилось в окне браузера пользователя. (К сожалению, я не контролирую размер исходных изображений.)

Так что-то вроде этого будет в HTML:

<img id="photo"
     src="a_really_big_file.jpg"
     alt="this is some alt text"
     title="this is some title text" />

Есть ли способ определить, было ли загружено изображение src в теге img?

Мне это нужно, потому что я столкнулся с проблемой, если $(document).ready() выполняется до того, как браузер загрузит изображение. $("#photo").width() и $("#photo").height() вернут размер заполнителя (альтернативный текст). В моем случае это что-то вроде 134 х 20.

Прямо сейчас я просто проверяю, меньше ли высота фотографии, чем 150, и предполагаю, что если это так, то это просто альтернативный текст. Но это довольно взломано, и оно сломается, если фотография будет иметь высоту менее 150 пикселей (в моем конкретном случае это маловероятно), или если высота альтернативного текста превышает 150 пикселей (это может произойти в небольшом окне браузера) .


Редактировать: Для тех, кто хочет увидеть код:

$(function()
{
  var REAL_WIDTH = $("#photo").width();
  var REAL_HEIGHT = $("#photo").height();

  $(window).resize(adjust_photo_size);
  adjust_photo_size();

  function adjust_photo_size()
  {
    if(REAL_HEIGHT < 150)
    {
      REAL_WIDTH = $("#photo").width();
      REAL_HEIGHT = $("#photo").height();
      if(REAL_HEIGHT < 150)
      {
        //image not loaded.. try again in a quarter-second
        setTimeout(adjust_photo_size, 250);
        return;
      }
    }

    var new_width = . . . ;
    var new_height = . . . ;

    $("#photo").width(Math.round(new_width));
    $("#photo").height(Math.round(new_height));
  }

});

Обновление : Спасибо за предложения. Существует риск того, что событие не будет запущено, если я установил обратный вызов для события $("#photo").load, поэтому я определил событие onLoad непосредственно в теге изображения. Для справки, вот код, с которым я закончил:

<img id="photo"
     onload="photoLoaded();"
     src="a_really_big_file.jpg"
     alt="this is some alt text"
     title="this is some title text" />

Тогда в Javascript:

//This must be outside $() because it may get called first
var isPhotoLoaded = false;
function photoLoaded()
{
  isPhotoLoaded = true;
}

$(function()
{
  //Hides scrollbars, so we can resize properly.  Set with JS instead of
  //  CSS so that page doesn't break with JS disabled.
  $("body").css("overflow", "hidden");

  var REAL_WIDTH = -1;
  var REAL_HEIGHT = -1;

  $(window).resize(adjust_photo_size);
  adjust_photo_size();

  function adjust_photo_size()
  {
    if(!isPhotoLoaded)
    {
      //image not loaded.. try again in a quarter-second
      setTimeout(adjust_photo_size, 250);
      return;
    }
    else if(REAL_WIDTH < 0)
    {
      //first time in this function since photo loaded
      REAL_WIDTH = $("#photo").width();
      REAL_HEIGHT = $("#photo").height();
    }

    var new_width = . . . ;
    var new_height = . . . ;

    $("#photo").width(Math.round(new_width));
    $("#photo").height(Math.round(new_height));
  }

});

Ответы [ 13 ]

31 голосов
/ 05 ноября 2008

Либо добавьте прослушиватель событий, либо попросите изображение объявить себя с помощью onload. Затем выясните размеры оттуда.

<img id="photo"
     onload='loaded(this.id)'
     src="a_really_big_file.jpg"
     alt="this is some alt text"
     title="this is some title text" />
14 голосов
/ 21 октября 2011

Используя хранилище данных jquery , вы можете определить состояние «загрузки».

<img id="myimage" onload="$(this).data('loaded', 'loaded');" src="lolcats.jpg" />

Тогда в другом месте вы можете сделать:

if ($('#myimage').data('loaded')) {
    // loaded, so do stuff
}
9 голосов
/ 29 сентября 2010

Правильный ответ - использовать event.special.load

Возможно, событие загрузки не будет запущено, если изображение загружено из кэша браузера. Чтобы учесть эту возможность, мы можем использовать специальное событие загрузки, которое запускается немедленно, если изображение готово. event.special.load в настоящее время доступен как плагин.

По документам .load ()

5 голосов
/ 05 ноября 2008

Вы хотите сделать то, что сказал Аллен, однако имейте в виду, что иногда изображение загружается до того, как все будет готово, что означает, что ваш обработчик загрузки не будет срабатывать. Лучший способ - сделать так, как говорит Аллен, но установить src изображения с помощью javascript после прикрепления инструмента загрузки. Таким образом, вы можете гарантировать его срабатывание.

Что касается доступности, будет ли ваш сайт работать для людей без javascript? Возможно, вы захотите присвоить тегу img правильный src, прикрепите обработчик dom ready для запуска js: очистите изображение src (установите фиксированное значение с и css для предотвращения мерцания страницы), затем установите обработчик загрузки img затем сбросьте src в правильный файл. Таким образом, вы охватите все базы:)

4 голосов
/ 02 апреля 2014

Согласно одному из последних комментариев к вашему первоначальному вопросу

$(function() {

  $(window).resize(adjust_photo_size);
  adjust_photo_size();

  function adjust_photo_size()  {
    if (!$("#photo").get(0).complete) {
       $("#photo").load(function() {
          adjust_photo_size();
       });
    } else {
      ... 
    }
});

Предупреждение Этот ответ может вызвать серьезную петлю в ie8 и ниже, потому что img.complete не всегда правильно устанавливается браузером. Если вы должны поддерживать ie8, используйте флаг, чтобы помнить, что изображение загружено.

3 голосов
/ 05 ноября 2008

Попробуйте что-то вроде:

$("#photo").load(function() {
    alert("Hello from Image");
});
2 голосов
/ 16 июля 2014

Я обнаружил, что это работает для меня

document.querySelector("img").addEventListener("load", function() { alert('onload!'); });

Кредит полностью принадлежит Фрэнку Швитерману, который прокомментировал принятый ответ Я должен был положить это здесь, это слишком ценно ...

2 голосов
/ 21 мая 2013

Существует плагин jQuery с именем «imagesLoaded», который обеспечивает кросс-браузерный метод, совместимый для проверки, загружены ли изображения элемента.

Сайт: https://github.com/desandro/imagesloaded/

Использование контейнера, в котором много изображений:

$('container').imagesLoaded(function(){
 console.log("I loaded!");
})

Плагин отличный:

  1. работает для проверки контейнера с большим количеством изображений внутри
  2. работает для проверки IMG, чтобы увидеть, загрузил ли он
2 голосов
/ 29 сентября 2010

Есть комментарии к этому?

...

doShow = function(){
  if($('#img_id').attr('complete')){
    alert('Image is loaded!');
  } else {
    window.setTimeout('doShow()',100);
  }
};

$('#img_id').attr('src','image.jpg');

doShow();

...

Кажется, работает везде ...

1 голос
/ 20 мая 2012

Эта функция проверяет, загружено ли изображение на основе измеряемых размеров. Этот метод полезен, если ваш скрипт выполняется после того, как некоторые изображения уже загружены.

imageLoaded = function(node) {
    var w = 'undefined' != typeof node.clientWidth ? node.clientWidth : node.offsetWidth;
    var h = 'undefined' != typeof node.clientHeight ? node.clientHeight : node.offsetHeight;
    return w+h > 0 ? true : false;
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...