Как создать обратный вызов JavaScript, чтобы знать, когда изображение загружается? - PullRequest
109 голосов
/ 11 ноября 2008

Я хочу знать, когда изображение закончило загрузку. Есть ли способ сделать это с помощью обратного вызова?

Если нет, есть ли способ сделать это вообще?

Ответы [ 8 ]

115 голосов

.complete + обратный вызов

Это совместимый со стандартами метод без дополнительных зависимостей, который ожидает не дольше, чем необходимо:

var img = document.querySelector('img')

function loaded() {
  alert('loaded')
}

if (img.complete) {
  loaded()
} else {
  img.addEventListener('load', loaded)
  img.addEventListener('error', function() {
      alert('error')
  })
}

Источник: http://www.html5rocks.com/en/tutorials/es6/promises/

59 голосов
/ 11 ноября 2008

Image.onload () часто будет работать.

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

Ссылки по теме:

Пример использования:

<html>
<head>
<title>Image onload()</title>
</head>
<body>

<img src="#" alt="This image is going to load" id="sologo"/>

<script type="text/javascript">
window.onload = function () {

    var logo = document.getElementById('sologo');

    logo.onload = function () {
        alert ("The image has loaded!");        
    };

    setTimeout(function(){
        logo.src = 'http://stackoverflow.com/Content/Img/stackoverflow-logo-250.png';         
    }, 5000);
};
</script>
</body>
</html>
20 голосов
/ 11 ноября 2008

Вы можете использовать свойство .complete класса изображений Javascript.

У меня есть приложение, в котором я храню несколько объектов Image в массиве, которые будут динамически добавляться на экран, и по мере их загрузки я пишу обновления для другого div на странице. Вот фрагмент кода:

var gAllImages = [];

function makeThumbDivs(thumbnailsBegin, thumbnailsEnd)
{
    gAllImages = [];

    for (var i = thumbnailsBegin; i < thumbnailsEnd; i++) 
    {
        var theImage = new Image();
        theImage.src = "thumbs/" + getFilename(globals.gAllPageGUIDs[i]);
        gAllImages.push(theImage);

        setTimeout('checkForAllImagesLoaded()', 5);
        window.status="Creating thumbnail "+(i+1)+" of " + thumbnailsEnd;

        // make a new div containing that image
        makeASingleThumbDiv(globals.gAllPageGUIDs[i]);
    }
}

function checkForAllImagesLoaded()
{
    for (var i = 0; i < gAllImages.length; i++) {
        if (!gAllImages[i].complete) {
            var percentage = i * 100.0 / (gAllImages.length);
            percentage = percentage.toFixed(0).toString() + ' %';

            userMessagesController.setMessage("loading... " + percentage);
            setTimeout('checkForAllImagesLoaded()', 20);
            return;
        }
    }

    userMessagesController.setMessage(globals.defaultTitle);
}
10 голосов
/ 06 февраля 2011

Вы можете использовать событие load () - в jQuery, но оно не всегда срабатывает, если изображение загружается из кэша браузера. Этот плагин https://github.com/peol/jquery.imgloaded/raw/master/ahpi.imgload.js может быть использован для решения этой проблемы.

6 голосов
/ 11 января 2018

Жизнь слишком коротка для jquery.

function waitForImageToLoad(imageElement){
  return new Promise(resolve=>{imageElement.onload = resolve})
}

var myImage = document.getElementById('myImage');
var newImageSrc = "https://pmchollywoodlife.files.wordpress.com/2011/12/justin-bieber-bio-photo1.jpg?w=620"

myImage.src = newImageSrc;
waitForImageToLoad(myImage).then(()=>{
  // Image have loaded.
  console.log('Loaded lol')
});
<img id="myImage" src="">
1 голос
/ 22 марта 2017

Вот эквивалент jQuery:

var $img = $('img');

if ($img.length > 0 && !$img.get(0).complete) {
   $img.on('load', triggerAction);
}

function triggerAction() {
   alert('img has been loaded');
}
0 голосов
/ 28 мая 2018

Если вы используете React.js, вы можете сделать это:

render() {

// ...

<img 
onLoad={() => this.onImgLoad({ item })}
onError={() => this.onImgLoad({ item })}

src={item.src} key={item.key}
ref={item.key} />

// ... }

Где:

- onLoad (...) теперь будет вызываться примерно так: {src: " https: //......png", ключ: "1"} Вы можете использовать это как «ключ», чтобы знать, какие изображения загружены правильно, а какие нет. - onError (...) то же самое, но для ошибок. - объект "item" выглядит примерно так {key: "..", src: ".."} Вы можете использовать для хранения URL и ключ изображений, чтобы использовать их в списке изображений.
0 голосов
/ 24 октября 2012

эти функции решат проблему, вам нужно реализовать функцию DrawThumbnails и иметь глобальную переменную для хранения изображений. Я люблю, чтобы это работало с объектом класса, у которого ThumbnailImageArray в качестве переменной-члена, но я изо всех сил!

называется как в addThumbnailImages(10);

var ThumbnailImageArray = [];

function addThumbnailImages(MaxNumberOfImages)
{
    var imgs = [];

    for (var i=1; i<MaxNumberOfImages; i++)
    {
        imgs.push(i+".jpeg");
    }

    preloadimages(imgs).done(function (images){
            var c=0;

            for(var i=0; i<images.length; i++)
            {
                if(images[i].width >0) 
                {
                    if(c != i)
                        images[c] = images[i];
                    c++;
                }
            }

            images.length = c;

            DrawThumbnails();
        });
}



function preloadimages(arr)
{
    var loadedimages=0
    var postaction=function(){}
    var arr=(typeof arr!="object")? [arr] : arr

    function imageloadpost()
    {
        loadedimages++;
        if (loadedimages==arr.length)
        {
            postaction(ThumbnailImageArray); //call postaction and pass in newimages array as parameter
        }
    };

    for (var i=0; i<arr.length; i++)
    {
        ThumbnailImageArray[i]=new Image();
        ThumbnailImageArray[i].src=arr[i];
        ThumbnailImageArray[i].onload=function(){ imageloadpost();};
        ThumbnailImageArray[i].onerror=function(){ imageloadpost();};
    }
    //return blank object with done() method    
    //remember user defined callback functions to be called when images load
    return  { done:function(f){ postaction=f || postaction } };
}
...