Изменения в Firefox browser.xul не обновляются в режиме реального времени - PullRequest
2 голосов
/ 23 мая 2011

Я сталкиваюсь с некоторой проблемой цикла событий при внесении изменений в реальном времени в browser.xul из расширения Firefox.Изменения, которые я делаю в browser.xul, не отображаются в окне браузера, пока мой код не завершится.Это происходит, даже когда я использую setTimeout.

У меня есть пример, который демонстрирует проблему ниже.Когда я нажимаю кнопку «xultest runtest», в течение нескольких секунд ничего не происходит, а затем текст xultest показывается как 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 Ответ

2 голосов
/ 23 мая 2011

То, как вы это делаете, с 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);
}
...