等待图像渲染完成

3
有没有一种原生的Javascript方法,在继续执行之前等待图像完全渲染?我需要在文档已经加载完成后才进行这个操作。根据Is there something like a ready event when an image in html is loaded and rendered?,文档的load事件会等待渲染完成。但是,我需要在文档初始加载完成后再加载图像。
人们似乎说要在图像元素上使用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: 我在load回调中添加了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";

load事件监听器中添加一个requestAnimationFrame()回调函数。 - undefined
@PatrickRoberts 我编辑了问题,包括requestAnimationFrame。请确保我按照您的意图进行了实现。我对requestAnimationFrame的理解仍然有限,所以这个实现并不起作用。 - undefined
你能否创建一个 [mcve]? - undefined
1
可能是与如何检测图像在浏览器中是否已完成渲染(即绘制)?相关的重复问题。 - undefined
2个回答

0
使用load事件。
$("img#test").on("load", function(event){
    //enter your code here
})

1
您的解决方案使用了超出问题范围的jQuery。虽然我没有针对jQuery的"load"事件处理程序进行测试,但JavaScript的load事件并不会在图像渲染完成时触发,因此我认为jQuery的处理程序也是一样的。 - undefined

0

requestAnimationFrame()的问题在于,在事件load之后,图像将在第二个动画帧上渲染。所以你走得对,只需在第一个requestAnimationFrame中调用另一个函数。

你可以尝试这样做:

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

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

function loaded()  {
    requestAnimationFrame(startRender);
}

<img onload="loaded();" src="http://ximmix.mixeriksson.com/bilder/iron_maiden_piece_of_mind_foldout_cleaned_3034x1500px_110412145556_2.jpg">

如果它有效,请同时给予#Hovitya的认可此帖子

这是他的jsfiddle示例


不要重复发布重复的内容,如果你复制的答案完全回答了问题,请将问题标记为重复并投票关闭。 - undefined
请参见编辑2。虽然这很有帮助,但并没有解决根本问题。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接