使用 MozAfterPaint 调试绘制

这篇文章最初由 Robert O’Callahan 发布在 Mozilla 的 web-tech 博客 上。它是 Firefox 3.5 中一个有趣的特性,并且值得作为我们 35 天计划的一部分在此重复介绍。

此外,Thomas Robinson 创建了一个非常方便的 书签,用于调试在浏览器中加载的页面上的绘制。

由于大众需求,我们为 Firefox 3.5 创建了一个 *非常* 实验性的 API,用于在每次内容重新绘制时触发一个事件。该事件称为 MozAfterPaint,并在文档上触发,冒泡到窗口。该事件提供了 两个属性clientRectsboundingClientRect,它们使用与 getClientRectsgetBoundingClientRect 方法相同的对象和坐标系来告诉您重新绘制的内容。

这对 Firefox 扩展和其他可能正在使用 canvas.drawWindow 方法捕获窗口内容的“chrome”代码 非常有用。它也可能对 Firebug 等工具有用。但它也可能对常规内容有用,例如,如果您想向页面添加一些轻量级的 JS 检测以衡量 Firefox 绘制的内容以及何时绘制。

注意事项:

  • 这仅适用于 Gecko。不要在公开的网页上将此用于实际功能 - 尽管我不确定为什么有人会这样做,所以我目前不认为这是标准化的候选对象。
  • 出于安全原因,常规 Web 内容只会收到在其自身文档中发生的重新绘制的通知 - 由 IFRAME 引起的重新绘制不会报告给附加到 IFRAME 的祖先的不受信任的监听器。(但是,由“受信任”内容(如 Firefox chrome)添加的监听器会收到窗口所有重新绘制的通知。)
  • 目前,该事件可能在实际重新绘制发生之前触发。这应该影响不大,我们将在某个时候修复它。
  • 如果您的事件处理程序执行任何触发重新绘制的操作,例如更改元素的样式,您可能会触发无限循环。浏览器应该保持响应,但您的机器将加剧全球变暖。
  • 会报告滚动到视口外部区域的重新绘制,但不会报告滚动到 overflow:auto 元素等外部区域的重新绘制。
  • 不会报告窗口插件(即 Windows 和 GTK 中的大多数插件)中的重新绘制。

4 条评论

  1. Wired Earp

    更棒的是一个“MozBeforePaint”事件,我可以对其调用 preventDefault(),也许可以结合一个按需触发重新绘制的设置。甚至可能是这样的:

    window.__disableRepaint ();
    // 构建 DOM 结构并更改 1000 个 className…
    window.__enableRepaint ();
    window.__repaint ();

    向评论读者提问:有人能想象使用 chrome 代码模拟此设置的方案吗?我还没有找到任何有用的东西,也许我只是不知道在哪里找。

    2009 年 6 月 23 日 02:05

  2. Boris

    Wired Earp,你提出的这种设置的问题是,作者往往会忘记_enableRepaint()。

    另一方面,如果您只是构建 DOM 结构,那么无论如何都不会进行重新绘制,除非您特别费心允许它(例如,使用 setTimeout 将其余工作推迟到稍后)。所以我不清楚你在这里到底想要什么。

    2009 年 6 月 23 日 16:53

  3. […] 原文地址:debugging painting with MozAfterPaint 系列地址:颠覆网络35天 […]

    2009 年 6 月 23 日 19:44

  4. lrbabe

    @Wired Earp:在同时切换 body 的可见性和更改 DOM 的某些类是可能的,而且用户不会注意到。并且它是跨浏览器的: )

    2009 年 6 月 24 日 12:47

本文评论已关闭。