Firefox browser.xul的更改不会实时更新

时间:2011-05-22 23:30:49

标签: javascript firefox firefox-addon xul

当从Firefox扩展程序对browser.xul进行实时更改时,我遇到了某种事件循环问题。在我的代码完成之前,我对browser.xul所做的更改不会反映在浏览器窗口中。即使我使用setTimeout也会发生这种情况。

我有一个示例,演示了下面的问题。当我点击“xultest runtest”按钮时,几秒钟内没有任何反应,然后xultest-text显示为XXXXXXXXXX。我从来没有看到过XX,XXX,XXXX ......。

有人可以解释一下browser.xul事件循环的情况以及如何解决它(谢谢!)?

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="css/overlay.css" type="text/css"?>
<overlay id="xultest-overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
    <script type="text/javascript">
        <![CDATA[
        function xultestRunTest2() {
            for (var i = 0; i < 10; i++) {
                setTimeout(function() {
                        document.getElementById("xultest-text").value =
                            document.getElementById("xultest-text").value + "X" },
                    5000);
            }
        }
        ]]>
    </script>
    <toolbox id="navigator-toolbox">
        <toolbar id="xultest-toolbar" toolbarname="xultesttoolbar" class="chromeclass-toolbar" context="toolbar-context-menu" hidden="false" persist="hidden">
            <toolbarbutton oncommand="xultestRunTest2();" label="xultest runtest" />
            <label id="xultest-text" class="toolbarbutton-text" value="X"></label>
        </toolbar>
    </toolbox>
</overlay>

1 个答案:

答案 0 :(得分:2)

你正在这样做的方式,在setTimeout循环中有一个for,你实际做的是创建十个单独的超时,这些超时大约会同时发生,大约5秒后单击按钮。

您需要做的是仅在上一次超时发生后创建每个新超时:

function xultestRunTest2(times) {
    if(times > 0){
        document.getElementById("xultest-text").value =
                        document.getElementById("xultest-text").value + "X";
        setTimeout(function(){ xultestRunTest2(times-1); }, 5000);
    }
}

...

<toolbarbutton oncommand="xultestRunTest2(10);" label="xultest runtest" />

或(这是我最喜欢的三种方法):

function xultestRunTest2() {
    var times = 10;
    function do_cycle(){
        var el = document.getElementById("xultest-text");
        if(times > 0){
            el.value = el.value + "X";
            setTimeout(do_cycle, 5000);
            --times;
        }
    };
    do_cycle();
}

您也可以使用setInterval()代替:

function xultestRunTest2() {
    var times = 10,
        intervalId;
    intervalId = setInterval(function(){
        if(times > 0){
            document.getElementById("xultest-text").value =
                        document.getElementById("xultest-text").value + "X";
            --times;
        }
        else {
            clearInterval(intervalId);
            intervalId = null;
        }
    }, 5000);
}