javascript - 对 Firefox browser.xul 的更改未实时更新

标签 javascript firefox firefox-addon xul

当从 Firefox 扩展对 browser.xul 进行实时更改时,我遇到了某种事件循环问题。在我的代码完成之前,我对 browser.xul 所做的更改不会反射(reflect)在浏览器窗口中。即使我使用 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>

最佳答案

你这样做的方式是,在 for 循环中使用 setTimeout,你有效地做的是创建十个独立的超时,它们将大致同时触发时间,点击按钮后 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);
}

关于javascript - 对 Firefox browser.xul 的更改未实时更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6091522/

相关文章:

javascript - 在多个元素上滚动到顶部

javascript - 正则表达式找不到 '\u2028' unicode 字符

html - 各种网站分析方法的优缺点是什么?

javascript - 可用于 Firefox 附加组件的 XMLHttpRequest 的更强大替代方案?

css - 如何在 Firefox WebExtension 上使用@font-face

javascript - 用于视频捕获的 Chrome 或 Firefox 扩展

javascript - Firebase 9 和 ref 函数与 Vue 组合

javascript - Emscripten,Embind,错误 : no instance of constructor

javascript - 如何在没有 Xcode 的情况下手动安装 Phonegap 库?

Firefox api - 从我的程序访问