I’m running into some sort of event loop issue when making real time changes to browser.xul from a Firefox extension. Changes I am making to the browser.xul are not reflected in the browser window until my code finishes. This happens even when I use setTimeout.
I have an example that demonstrates the issue below. When I click on the “xultest runtest” button nothing happens for a few seconds and then the xultest-text is shown as XXXXXXXXXX. I never see the XX,XXX,XXXX… in between.
Can someone explain what is going on with the browser.xul event loop and how to work around it (thanks!)?
<?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>
The way you’re doing it, with a
setTimeoutinside aforloop, what you effectively do is create ten separate timeouts that will all fire approximately at the same time, 5 seconds after you click the button.What you need to do is create each new timeout only after the previous one fires:
or (this is my favorite method of the three):
You could also use
setInterval()instead: