如何从XUL iframe正确接收DOMContentLoaded事件?

时间:2012-06-24 01:30:47

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

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

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

但是,到目前为止,我只能收到load个活动 - 而不是loadDOMContentLoaded个活动。

使用下面的XUL可以轻松重现该问题,只需在Firefox位置栏中输入XUL的路径,并指定其readyState网址(类似于this):

chrome://

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

<?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!输出。

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

我已经引用的页面包括:

我已经在irc.mozilla.org/#extdev上提到了这一点,并且只能获得“为其他人工作”的响应,并且“尽管如此,最好使用捕获侦听器”。 - 这就是为什么我在所有上述readystatechange:次调用中将第3个useCapture参数设置为true的原因(尽管我没有注意到将此设置为false或完全省略它的任何差异)。

我希望以“正确的方式”做到这一点,而无需在addEventListener上进行投票。

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

2 个答案:

答案 0 :(得分:2)

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

  

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

Firefox和Opera(Mini或桌面12及其下​​使用Presto引擎)支持此事件:

  

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

     

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

     

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

<强>参考

答案 1 :(得分:1)

通过Firefox菜单打开XUL页面时是否会出现问题&gt; Web开发人员&gt;错误控制台&gt; open("chrome://yourpage.xul", "", "width=640,height=480");?位置栏下方的浏览器被标记为content-primary,这使得其中的页面以受限制的权限运行,而不管页面来自哪个协议(这是违反直觉的,授予的)。这可能是导致你的问题的原因,但不幸的是,我无法告诉你确切的原因。

这些微妙问题的下一步是连接到irc.mozilla.org#developers并在西海岸清醒时询问你的问题:)。