2014-10-06 50 views
0

考慮以下的(簡化的)例子正常工作:gBrowser.getBrowserAtIndex(I)有時會失敗上removeTab()

var tabs = window.gBrowser.tabs; 
for (var i = 2, len = tabs.length; i < len; i++) { 
    var uri = window.gBrowser.getBrowserAtIndex(i).currentURI.spec; 
} 

以下有時最後標籤上失敗,提示信息窗口.gBrowser.getBrowserAtIndex(...)是未定義

var tabs = window.gBrowser.tabs; 
for (var i = 2, len = tabs.length; i < len; i++) { 
    var uri = window.gBrowser.getBrowserAtIndex(i).currentURI.spec; 
    window.gBrowser.removeTab(window.gBrowser.tabContainer.childNodes[i]); 
} 

我不明白爲什麼失敗,爲什麼它只是偶爾的失敗不是所有的時間。

是否有任何其他方法可以用來代替gBrowser.getBrowserAtIndex(i)來獲取標籤的URL?

回答

1

看起來您正在關閉一個循環,其中您已經存儲了初始選項卡數len = tabs.length,然後在現有選項卡數量可能因您的操作而發生更改時與原始選項卡數進行比較。

的構建:
for (let i = 2, len = tabs.length; i < len; i++) {...}
是其中的tabs長度將不改變的條件下更有效。但是,在這種情況下,您要更改選項卡的數量,並且每次檢查此循環的終止條件時都需要與tabs.length進行比較。所以:
for (let i = 2, len = tabs.length; i < len; i++) {...}
事實上,當前的循環不會總是失敗的唯一原因是window.gBrowser.removeTab()之前實際上被刪除的選項卡返回。您正在進行比賽,看看您是否在任何製表符被移除之前完成循環。

但是,這不是唯一的問題。您正在移除您當前編入索引的選項卡。在大多數情況下,如果選項卡被移除,就像大多數數組一樣,剩下的較高索引選項卡會向下移動到您正在處理的索引處。當前循環不會經常跳過每個其他選項卡的唯一原因是window.gBrowser.removeTab()在實際刪除當前索引的選項卡之前返回。在您看到undefined錯誤的場合,您實際上只跳過一個選項卡。

你的循環真的應該是這樣的:
for (let i = tabs.length - 1; i >=2; i--) {...}
這樣,您就開始在列表的末尾,並從那裏下來刪除。這可以避免undefined問題以及通過消除在實際刪除任何選項卡之前需要完成整個過程的爭用情況而跳過選項卡的可能性。

+0

謝謝...很好的解釋:) – erosman 2014-10-06 12:15:23

+0

代碼需要一個小的修正...'的(讓我= tabs.length - 1; i> = 2; i--){...}'......讓我重新開始注意它; – erosman 2014-10-06 13:00:29

+0

謝謝,我解決了這個錯誤。當沒有實際測試時,我不應該編碼)8)。 – Makyen 2014-10-06 14:23:12

1

根本問題是tabs不是一個數組,而是一個NodeList,它是一個實時集合。當您撥打removeTab()時,更改將反映在NodeList(長度,索引)中。

爲了避免這些副作用將其轉換爲一個真正的數組

var tabsArr = [].slice.call(gBrowser.tabs); 
+0

謝謝..我知道我錯過了一些東西:) – erosman 2014-10-06 12:14:52