Проверка нескольких загруженных изображений - PullRequest
10 голосов
/ 13 июня 2010

Я использую функцию canvas в html5.У меня есть несколько изображений для рисования на холсте, и мне нужно проверить, все ли они загружены, прежде чем я смогу их использовать.

Я объявил их внутри массива, мне нужен способ проверить, есть ли онивсе загружены одновременно, но я не уверен, как это сделать.

Вот мой код:

var color = new Array();
color[0] = new Image();
color[0].src = "green.png";
color[1] = new Image();
color[1].src = "blue.png";

В настоящее время, чтобы проверить, загружены ли изображения, я должен был бы сделатьэто одно за другим, вот так:

color[0].onload = function(){
//code here
}
color[1].onload = function(){
//code here
}

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

Как бы я проверил их все одновременно?

Ответы [ 6 ]

25 голосов
/ 20 ноября 2012

Если вы хотите вызвать функцию, когда все изображения загружены, можете попробовать следующее, у меня это сработало

var imageCount = images.length;
var imagesLoaded = 0;

for(var i=0; i<imageCount; i++){
    images[i].onload = function(){
        imagesLoaded++;
        if(imagesLoaded == imageCount){
            allLoaded();
        }
    }
}

function allLoaded(){
    drawImages();
}
10 голосов
/ 13 июня 2010

Разве вы не можете просто использовать цикл и назначить одну и ту же функцию всем нагрузкам?

var myImages = ["green.png", "blue.png"];

(function() {
  var imageCount = myImages.length;
  var loadedCount = 0, errorCount = 0;

  var checkAllLoaded = function() {
    if (loadedCount + errorCount == imageCount ) {
       // do what you need to do.
    }
  };

  var onload = function() {
    loadedCount++;
    checkAllLoaded();
  }, onerror = function() {
    errorCount++;
    checkAllLoaded();
  };   

  for (var i = 0; i < imageCount; i++) {
    var img = new Image();
    img.onload = onload; 
    img.onerror = onerror;
    img.src = myImages[i];
  }
})();
3 голосов
/ 13 июня 2010

Используйте window.onload, который срабатывает при загрузке всех изображений / кадров и внешних ресурсов:

window.onload = function(){
  // your code here........
};

Таким образом, вы можете безопасно поместить свой код, связанный с изображениями, в window.onload, потому что к тому времени все изображения уже загружены.

Более подробная информация здесь.

2 голосов
/ 13 июня 2010

Хакерский способ сделать это - добавить команду JS в другой файл и поместить ее в нижний колонтитул. Таким образом, он загружается последним.

Однако использование jQuery (документа) .ready также работает лучше, чем встроенное окно .onload.

Вы используете Chrome, не так ли?

1 голос
/ 25 октября 2018
Метод

Just onload в for loop не решает эту задачу, поскольку метод onload выполняется асинхронно в цикле.Так что большие изображения в середине цикла могут быть пропущены в случае, если у вас есть какой-то обратный вызов только для последнего изображения в цикле.

Вы можете использовать Async Await, чтобы связать цикл для отслеживания загрузки изображениясинхронно.

function loadEachImage(value) {
   return new Promise((resolve) => {
      var thumb_img = new Image();
      thumb_img.src = value;
      thumb_img.onload = function () {
         console.log(value);
         resolve(value); // Can be image width or height values here
      }
   });
}

function loadImages() {
   let i;
   let promises = [];

   $('.article-thumb img').each(function(i) {
      promises.push(loadEachImage( $(this).attr('src') ));
   });

   Promise.all(promises)
      .then((results) => {
          console.log("images loaded:", results); // As a `results` you can get values of all images and process it
      })
      .catch((e) => {
         // Handle errors here
      });
}

loadImages();

Но недостаток этого метода в том, что он увеличивает время загрузки, поскольку все изображения загружаются синхронно.


Также вы можете использовать простой for loop и запускать обратный вызов после каждой итерации для обновления / обработки последнего загруженного значения изображения.Чтобы вам не приходилось ждать, когда меньшие изображения загружаются только после самого большого.

var article_thumb_h = [];
var article_thumb_min_h = 0;

$('.article-thumb img').each(function(i) {
   var thumb_img = new Image();
   thumb_img.src = $(this).attr('src');
   thumb_img.onload = function () {
      article_thumb_h.push( this.height ); // Push height of image whatever is loaded
      article_thumb_min_h = Math.min.apply(null, article_thumb_h); // Get min height from array
      $('.article-thumb img').height( article_thumb_min_h ); // Update height for all images asynchronously
   }
});

Или просто используйте этот подход , чтобы сделать обратный вызов после загрузки всех изображений.

Все зависит от того, что вы хотите сделать.Надеюсь, это кому-нибудь поможет.

0 голосов
/ 09 мая 2019

попробуйте этот код:

<div class="image-wrap" data-id="2">
<img src="https://www.hd-wallpapersdownload.com/script/bulk-upload/desktop-free-peacock-feather-images-dowload.jpg" class="img-load" data-id="1">
<i class="fa fa-spinner fa-spin loader-2" style="font-size:24px"></i>
</div>

<div class="image-wrap" data-id="3">
<img src="http://diagramcenter.org/wp-content/uploads/2016/03/image.png" class="img-load" data-id="1">
<i class="fa fa-spinner fa-spin loader-3" style="font-size:24px"></i>
</div>
<script type="text/javascript">
    jQuery(document).ready(function(){
        var allImages = jQuery(".img-load").length;
        jQuery(".img-load").each(function(){
            var image = jQuery(this);
            jQuery('<img />').attr('src', image.attr('src')).one("load",function(){
                var dataid = image.parent().attr('data-id');
                console.log(dataid);
                 console.log('load');
            });
        });

    });

</script>
...