等待图像完成渲染

时间:2018-11-22 04:06:57

标签: javascript

香草Javascript中是否有一种方法可以等到图像完全渲染后再继续执行?我需要在文档已加载后进行。根据{{​​3}},文档的加载事件等待渲染完成。但是,我需要在最初加载文档后加载图像。

人们似乎说要在图片元素上使用load事件。但是,元素的load事件仅检测何时加载图像,而不是何时完成渲染。

例如,我将一个图像标签设置为视口的大小:

<img id="test" style="width: 100vw; height: 100vh;"></img>

然后,以下代码将一个非常大的图像加载到标签中(我正在测试的图像具体为7360x4912,但是该过程应适用于所有图像尺寸):

var img = document.getElementById("test");
img.addEventListener("load", function () {
    alert("Image is loaded but not necessarily rendered");
});
img.src = "ExtremelyLargeImage.jpg";

但是,当事件触发时,图像无法完全渲染(即显示为全白色或部分白色)。

此处避免使用任意长的setTimeout至关重要,尤其是因为PC和移动浏览器之间的渲染时间可能会大不相同。

最后,我知道可以将不同的图像尺寸提供给不同的屏幕尺寸,而不是仅对所有屏幕使用一个大图像。但是,为此,我必须能够检测图像何时完成渲染,因此实际图像尺寸无关紧要。

修改1: 我在加载回调中添加了requestAnimationFrame,将警报放入requestAnimationFrame的回调中:

var img = document.getElementById("test");
img.addEventListener("load", function () {
    requestAnimationFrame(function () {
        alert("Image load");
    });
});
img.src = "ExtremelyLargeImage.jpg";

按预期,这不起作用,因为requestAnimationFrame在下一次重绘之前执行其回调。

编辑2:

在堆栈中添加第二个requestAnimationFrame层与仅拥有一个具有相同的问题。基本上,现在它正在第一次和第二次重绘之间执行警报,而不是在第一次重绘之前执行警报。但是,不能保证那时之前图像已被完全绘制。不过,这是一个进步。

var img = document.getElementById("test");
img.addEventListener("load", function () {
    requestAnimationFrame(function () {
        requestAnimationFrame(function () {         
            alert("Image load");
        });
    });
});
img.src = "ExtremelyLargeImage.jpg";

2 个答案:

答案 0 :(得分:0)

> db.players.find() { "_id" : ObjectId("5bf8c75ae2b9040f6298d46f"), "isAlive" : true, "gamer" : ObjectId("5bf236cf36b3ee339d268eab"), "kills" : 202, "deaths" : 33, "__v" : 0 } { "_id" : ObjectId("5bf8c75ae2b9040f6298d470"), "isAlive" : true, "gamer" : ObjectId("5bf4dffda9299a1e88fdbacd"), "kills" : 46, "deaths" : 31, "__v" : 0 } { "_id" : ObjectId("5bf8c75ae2b9040f6298d472"), "isAlive" : true, "gamer" : ObjectId("5bf4e006a9299a1e88fdbacf"), "kills" : 34, "deaths" : 202, "__v" : 0 } { "_id" : ObjectId("5bf8c75ae2b9040f6298d471"), "isAlive" : true, "gamer" : ObjectId("5bf4e003a9299a1e88fdbace"), "kills" : 76, "deaths" : 11, "__v" : 0 } > db.matches.find() { "_id" : ObjectId("5bf8c75ae2b9040f6298d473"), "finished" : false, "room" : ObjectId("5bf4e29460e3af20eb842a3b"), "team_one" : [ { "_id" : ObjectId("5bf8c75ae2b9040f6298d46f") }, { "_id" : ObjectId("5bf8c75ae2b9040f6298d470") } ], "team_two" : [ { "_id" : ObjectId("5bf8c75ae2b9040f6298d471") }, { "_id" : ObjectId("5bf8c75ae2b9040f6298d472") } ], "__v" : 0 } 的问题可能是,事件requestAnimationFrame()之后,将在 second 动画帧上渲染img。因此,您走在正确的道路上,只需在首先 requestAnimationFrame

上调用另一个函数

所以您可以尝试这样的事情:

load

<script>
function rendered() {
    //Render complete
    alert("image rendered");
}

function startRender() {
    //Rendering start
    requestAnimationFrame(rendered);
}

function loaded()  {
    requestAnimationFrame(startRender);
}

如果可行,还应将#Hovitya this post

这是他的jsfiddle example

答案 1 :(得分:0)

使用加载事件。

$("img#test").on("load", function(event){
    //enter your code here
})