javascript - 如何确定浏览器何时完成插入元素的绘制?

标签 javascript

我有一个网页正在注入(inject)通过 AJAX 传送的 HTML。 先验我不知道内容的大小,但我需要根据内容的大小在页面上定位内容。这是一个不起作用的简单方法:

  1. 将父容器的不透明度设置为 0。
  2. 将内容插入 DOM。
  3. 测量尺寸,例如$el.outerWidth(true)
  4. 根据这些尺寸定位内容。
  5. 将父容器的不透明度(背面)设置为 1.0。

这种方法的问题在于内容非常复杂并且包含图像。调用 outerWidth() 时,浏览器尚未完成重新绘制屏幕,​​因此返回的尺寸不准确。 (有趣的是,在我的例子中,初始尺寸总是明显大于最终值,而不是我预期的 0。)

我可以通过在第 2 步和第 3 步之间设置一个计时器来减少这个问题,但是无论我将计时器设置多长时间,某些系统上肯定会有一些浏览器会超过它。如果我让计时器足够长以涵盖大多数情况,那将通过引入不必要的延迟来惩罚使用更快系统的用户。尽管下面引用的一些答案表明 setTimeout(fn, 0) 就足够了,但我发现情况并非如此。我在 2012 款 MacBook Air 上测得的绘制时间高达 60 毫秒,下面的一个答案建议为 500 毫秒。

看起来 Mozilla 曾经有一个 onPaint event这可能已经解决了我的问题......如果它仍然存在并且其他浏览器已经采用它的话。 (两者都不是。)和Mutation Observers在报告元素变化时似乎没有考虑绘制时间。

非常感谢解决方案或评论。如下所述,之前有人问过这个问题,但大多数问题至少有一年的历史了,我迫不及待地想再试一次。


不幸的是,相关问题没有提供可行的答案


更新:看来这个问题根本没有通用的解决方案。在我的具体案例中,我发现了一个属性,一旦内容被加载并且布局完成,它就会可靠地改变。 JavaScript 轮询此属性的更改。一点也不优雅,但这是我能找到的最佳选择。

最佳答案

我已经开始研究目前的情况,我的解决方案是这样的:

doSomeDomManipulation();
requestAnimationFrame(() => {
  setTimeout(() => {
    alert("finished painting");
  }, 0);
});

此方法的来源:

这曾经在 old MDN page on the topic of MozAfterPaint 的注释中:

“想要在页面重绘后执行操作的网页可以使用带有回调的 requestAnimationFrame,将超时设置为零,然后调用执行所需的重绘后操作的代码。”

关于javascript - 如何确定浏览器何时完成插入元素的绘制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19737762/

相关文章:

javascript - 通过 ajax 将命名数组发送到 PHP

javascript - 为什么 document.write ("-->") 没有按预期工作?

javascript - JQuery 鼠标事件 : How to trigger a callback if the element moves?

javascript - 如何轻松显示隐藏div INSIDE div?

javascript - Firefox 扩展 : multiple requests with XMLHttpRequest. 是否使用异步?

javascript - 如何退出 setInterval

javascript - 函数完成时 Nodejs 回调下一个循环

javascript - 仅在选择文件后显示加载程序,并在单击取消或十字按钮时隐藏

javascript - 当它们排在下一个时,如何不切换到第一个或最后一个 "li element"?

javascript - 在对象数组中搜索特定项目并查询属性是否存在