2014-10-06 24 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