当从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>
答案 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);
}