0

我有一个 chrome 扩展浏览器操作,我想列出一系列链接,并在当前选项卡中打开任何选定的链接。到目前为止,我所拥有的是这个,使用 jquery:

var url = urlForThisLink;
var li = $('<li/>');
var ahref = $('<a href="#">' + title + '</a>');
ahref.click(function(){
    chrome.tabs.getSelected(null, function (tab) {
        chrome.tabs.update(tab.id, {url: url});
    });
});
li.append(ahref);

它部分有效。它确实导航当前选项卡,但只会导航到最后以这种方式创建的任何链接。我怎样才能为一系列迭代的链接做到这一点?

4

2 回答 2

2

@jmort253 的回答实际上很好地说明了您的错误可能是什么。尽管是在for循环内声明的,url但它具有函数范围,因为它是用var. 因此,您的单击处理程序闭包绑定到for循环外部范围的变量,并且闭包的每个实例都使用相同的值,即。最后一个。

一旦 Chrome 支持该let关键字,您就可以使用它来代替它,var并且它会正常工作,因为url它将被限制在for循环体中。同时,您必须通过在函数中创建闭包来创建新范围:

function makeClickHandler(url) {
    return function() { ... };
}

for循环内部说:

for (var i = 0; i < urls.length; i++) {
    var url = urls[i]; 
    ...    
    ahref.click(makeClickHandler(url));
    ...
}
于 2012-10-14T08:37:05.287 回答
0

在您的代码示例中,您似乎只有一个链接。相反,让我们假设您有一个实际的链接集合。在这种情况下,您可以使用 for 循环来遍历它们:

// collection of urls
var urls = ["http://example.com", "http://domain.org"];

// loop through the collection, for each url, build a separate link.
for(var i = 0; i < urls.length; i++) {

    // this is the link for iteration i
    var url = urls[i]; 

    var li = $('<li/>');
    var ahref = $('<a href="#">' + title + '</a>');
    ahref.click( (function(pUrl) {
        return function() {
            chrome.tabs.getSelected(null, function (tab) {
                chrome.tabs.update(tab.id, {url: pUrl});
            });
        }
    })(url));
    li.append(ahref);
}

在编写原始答案时,我完全忘记了范围,因此我根据 Matthew Gertner 的答案对其进行了更新以使用闭包。基本上,在 click 事件处理程序中,我现在将 url 变量传递给一个匿名 1 参数函数,该函数返回另一个函数。返回的函数使用传递给匿名函数的参数,因此其状态不受 for 循环的下一次迭代将更改 url 的值这一事实的影响。

于 2012-10-14T01:50:06.380 回答