2011-05-22 47 views
2

從Firefox擴展中對browser.xul進行實時更改時,我遇到了某種事件循環問題。直到我的代碼完成後,我對browser.xul所做的更改纔會反映在瀏覽器窗口中。即使使用setTimeout,也會發生這種情況。Firefox browser.xul的實時更新

我有一個示例演示了下面的問題。當我點擊「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> 

回答

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); 
} 
+0

唉,我試圖將我的問題縮小到一個簡單的測試用例,我寫了問題中的錯誤代碼。我將回到創建測試用例的畫板上,一旦擁有它就會回到線程。我真的很感謝你在這方面的努力。如果我最終得到一個完全不同的測試用例,我會考慮創建一個新問題並調整這個問題來給你接受。謝謝!。 – studgeek 2011-05-24 02:15:09

+0

@studgeek哈哈,沒問題。隨意編輯這個問題。 – Zecc 2011-05-25 09:32:52

+0

我還沒有把這個縮小到簡單的問題。我現在認爲它與FF如何對XHR和iframe進行線程分析有關。我做了很多兩個。如果解析導致延遲,我不會感到驚訝,但我並不期待跳過。也許Firefox以某種方式批量重繪事件?無論如何,仍然在一個很好的例子。我將嘗試使用firebug-paint-events插件來查看它是否提供了任何見解。 – studgeek 2011-06-01 18:43:14