如何创建一个 JavaScript 回调函数来知道图像何时加载?

我想知道什么时候一个图像已经完成加载。有没有一种方法可以做到这一点与回调?

如果没有,有什么办法可以做到吗?

236806 次浏览

Onload () 通常可以工作。

要使用它,您需要确保在设置 src 属性之前绑定事件处理程序。

相关连结:

示例用法:

    window.onload = function () {


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


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


setTimeout(function(){
logo.src = 'https://edmullen.net/test/rc.jpg';
}, 5000);
};
 <html>
<head>
<title>Image onload()</title>
</head>
<body>


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


<script type="text/javascript">


</script>
</body>
</html>

可以使用 Javascript 映像类的. complete 属性。

我有一个应用程序,我在一个数组中存储了许多 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);
}

您可以在 jQuery 中使用 load ()-event,但是如果图像是从浏览器缓存加载的,它不会总是触发。这个插件 https://github.com/peol/jquery.imgloaded/raw/master/ahpi.imgload.js可以用来解决这个问题。

这些函数将解决这个问题,你需要实现 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 } };
}

.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/

下面是与 jQuery 等价的:

var $img = $('img');


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


function triggerAction() {
alert('img has been loaded');
}

对于 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="">

如果你使用 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”,key: “1”} 您可以使用这个作为“键”来知道哪些图像被正确加载,哪些没有。
  • - onError (...)它是相同的,但对于错误。
  • 对象“ item”类似于这样{ key: “ . .”,src: “ . .”} 您可以用来存储图像的 URL 和键,以便在图像列表中使用。

  • 如果目标是在浏览器呈现图像后设置 img 的样式,则应该:

    const img = new Image();
    img.src = 'path/to/img.jpg';
    
    
    img.decode().then(() => {
    /* set styles */
    /* add img to DOM */
    });
    

    因为浏览器先是 loads the compressed version of image,然后是 decodes it,最后是 paints。由于没有事件的 paint你应该运行你的逻辑后,浏览器有 decoded的 img 标记。

    这个问题在2008年提出时并不合适,但如今这个问题对我很有效:

    async function newImageSrc(src) {
    // Get a reference to the image in whatever way suits.
    let image = document.getElementById('image-id');
    
    
    // Update the source.
    img.src = src;
    
    
    // Wait for it to load.
    await new Promise((resolve) => { image.onload = resolve; });
    
    
    // Done!
    console.log('image loaded! do something...');
    }