【问题标题】:How to properly receive the DOMContentLoaded event from an XUL iframe?如何正确接收来自 XUL iframe 的 DOMContentLoaded 事件?
【发布时间】:2012-06-24 01:30:47
【问题描述】:

我正在开发一个将网页加载到 XUL iframe 中的最小 Firefox 扩展。 (我也尝试了html:iframe,但得到了相同的结果。)页面可能需要一些时间才能完全加载 - 我正在尝试接收DOMContentLoaded 事件,它应该在load 事件之前发生。

(主要原因是我试图注入 CSS 样式表,这应该在 DOMContentLoaded 事件之后立即完成,而不是等待页面出现“无样式”直到加载事件。但是,这将也可用于其他原因,因此特定于 CSS 的替代方案不是可行的解决方法。)

但是,到目前为止,我只能收到 load 事件 - 而不是 DOMContentLoadedreadyState 事件。

使用下面的 XUL 应该很容易重现该问题,只需在 Firefox 位置栏中输入 XUL 的路径,给出其chrome:// URL(类似于this):

<?xml version="1.0"?>
<!DOCTYPE window>
<window xmlns:html="http://www.w3.org/1999/xhtml"
        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">

    <script type="application/x-javascript">
        window.addEventListener("DOMContentLoaded", function(event){
            try{
                var outElem = document.getElementById("out");
                var out = function(s){
                    outElem.value += s + "\n";
                };

                var frameTest = document.getElementById("iframe-test");

                out("start: " + frameTest.contentDocument.readyState);
                frameTest.addEventListener("DOMContentLoaded",
                    function(e){
                        out("DOMContentLoaded! " + e);
                    },
                    true);
                frameTest.addEventListener("readystatechange",
                    function(e){
                        out("readystatechange: " + e);
                    },
                    true);
                frameTest.addEventListener("load",
                    function(e){
                        out("load: " + e + ", state: " + frameTest.contentDocument.readyState);
                    },
                    true);
                out("all listeners registered, frame location: " + frameTest.contentWindow.location + ", state: " + frameTest.contentDocument.readyState);
            }catch(e){
                alert(e);
            }
        }, true);
    </script>

    <iframe id="iframe-test" type="content" src="http://www.google.com" height="400" width="400"/>
    <textbox id="out" rows="10" cols="80" multiline="true"/>

</window>

我在调试文本框中收到的输出是:

start: uninitialized
all listeners registered, frame location: about:blank, state: uninitialized
load: [object Event], state: complete

我不知道为什么我没有收到任何 DOMContentLoaded!readystatechange: 输出。

https://gist.github.com/2985342 上提供了另一个同样不起作用的最小示例。

我已经参考过的页面包括:

我在 irc.mozilla.org/#extdev 上提到了这一点,但只能获得“对其他人有效。”和“最好使用捕获侦听器”的响应。 - 这就是为什么我在上述所有 addEventListener 调用中将第三个 useCapture 参数设置为 true (尽管我还没有注意到将它设置为 false 或完全省略它的任何区别)。

我希望以“正确的方式”做到这一点,而不是在 contentDocument.readyState 上进行投票。

更新: 例如,当通过“实时 XUL 编辑器”(https://addons.mozilla.org/en-US/firefox/addon/extension-developer/ 的一部分)进行采样时,此示例和其他类似示例按预期工作 - 但在作为 @987654343 加载时不会@ 文件。当通过位置栏加载时,是否存在导致此问题的受限权限等?

【问题讨论】:

    标签: javascript dom firefox-addon dom-events xul


    【解决方案1】:

    根据 Gecko 文档,DOMFrameContentLoaded 应该用作替代事件侦听器:

    DOMFrameContentLoaded 事件在框架完成加载和解析时执行,无需等待样式表、图像和子框架完成加载。此事件与 DOMContentLoaded 类似,但仅适用于帧。

    Firefox 和 Opera(Mini 或 desktop 12 并在其下使用 Presto 引擎)支持此事件:

    目前,Firefox 和 Opera 都实现了 DOMFrameContentLoaded 事件。

    当一个框架被加载时,Opera 会在所有者iframe 上调度一个事件。然后此事件会冒泡到window

    Firefox 在所有者iframe 上的文档上调度一个事件。它冒泡到window。该元素的目标是其内容已加载的iframe。如果所有者文档本身包含在frame 中,则会向父文档分派一个事件。 event target 仍然是加载内容时的框架(依此类推到父文档链的顶部)。

    参考文献

    【讨论】:

      【解决方案2】:

      当您通过 Firefox 菜单 > Web 开发人员 > 错误控制台 > open("chrome://yourpage.xul", "", "width=640,height=480"); 打开 XUL 页面时,是否会出现此问题?地址栏下方的浏览器被标记为内容主,这使得其中的页面以受限的权限运行,而不管页面来自什么协议(这是违反直觉的,被授予)。这可能是导致您的问题的原因,但很遗憾,我无法告诉您确切的原因。

      此类微妙问题的下一步涉及连接到 irc.mozilla.org#developers 并在西海岸清醒时询问您的问题 :)。

      【讨论】:

      • 没有区别。窗口弹出,但我看到每行相同的 3 行调试输出 - 没有 DOMContentLoaded!readyStateChange 输出。不过,请参阅上面的更新 - 它适用于“实时 XUL 编辑器”。我看到其他只能在 Chrome 权限下工作的东西,所以我认为这不是问题 - 但可能应该进一步调查。
      • 正确,如果您的代码也不能在独立窗口中运行,那不是因为我想到的权限限制代码。
      猜你喜欢
      • 2013-08-15
      • 2016-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-29
      • 2014-09-17
      相关资源
      最近更新 更多