Chrome扩展程序:从标签中提取关键字无效

时间:2013-11-11 10:08:55

标签: javascript google-chrome-extension

我正在编写一个Chrome扩展程序来存储链接,其方式与Delicious相似。作为我的扩展的一部分,我想保存我正在存储的链接的关键字。为了获得这个关键字,我使用以下函数:

EXT.get_keywords = function (tab) {
var keywords = [];

    if(tab) {
        chrome.tabs.executeScript(tab.id, {file:"js/keywords.js"},
            (function(keywords) {
                return function (res) {
                    var kw_str = res && res[0];
                    if (kw_str) {
                        keywords.push.apply(keywords, kw_str.split(","));
                    }
                }
            })(keywords));
    }
    console.log(keywords);
    return keywords;
}    

“js / keywords.js”文件的内容如下:

var metas = document.getElementsByTagName('meta'),
    i = 0,
    result = "";

for (i = 0; i < metas.length; i++) {
    if (metas[i].getAttribute("name") === "keywords") {
        result = metas[i].getAttribute("content");
        break;
    }
}
result;

“js / keywords.js”脚本运行良好,回调函数从关键字标签获取内容字符串(如果存在),但在执行回调后,关键字变量始终为[]。有什么想法吗?

PS:这很奇怪,因为如果我在console.log(keywords)行执行带有断点的脚本它可以工作,但如果断点不存在则不会:S。

1 个答案:

答案 0 :(得分:1)

这是由于 chrome.tabs.executeScript()的异步性质。您无法从get_keywords函数返回关键字 - 实际上您可以返回空keywords数组,但在函数退出之前不会填充它。
(大多数 chrome。* API都是异步的,因此您必须调整整个扩展“样式”以符合此要求。)

那么,会发生什么?

这是执行顺序:

  1. 初始化空keywords数组(var keywords = [];)。
  2. executeScript被称为在后台启动一些非常有用的东西。
  3. 调用
  4. (function(keywords) {...})(keywords),返回并注册一个回调(绑定到仍为空的keywords数组)。每次注入和执行结束时都会调用回调函数。
  5. executeScript返回(请注意,还没有执行回调 - 仍然在后台执行操作,即注入和执行JS)。
  6. console.log(keywords);记录(仍为空)keywords数组。
  7. 返回仍为空的keywords数组(return keywords;)。
  8. 异步注入/执行结束并调用回调,填充keywords数组。
  9. 如果激活断点,则在到达步骤5之前有时间完成注入/执行,因此在返回之前填充keywords数组。


    演示此内容的示例扩展程序:

    background.js 中,keywords数组会被记录两次:一次在getKeywords()返回之前,一次在回调中填充之后。正如您所看到的那样,在 getKeywords()返回一个空数组后执行回调登录。

    <强> content.js:

    var metas = document.getElementsByTagName("meta");
    var result = "";
    for (var i = 0; i < metas.length; i++) {
        var meta = metas[i];
        if (meta.name && (meta.name.toLowerCase() === "keywords")) {
            result = meta.content;
            break;
        }
    }
    result;
    

    <强> background.js:

    function getKeywords(tab) {
        var keywords = [];
    
        chrome.tabs.executeScript(
                tab.id,
                { file: "/fg/content.js" },
                (function(keywords) {
                    return function(resultArr) {
                        if (!chrome.runtime.lastError && resultArr[0]) {
                            keywords.push.apply(keywords, resultArr[0].split(","));
                        }
                        console.log("After: ", keywords);
                    }
                })(keywords));
        console.log("Before: ", keywords);
    }
    
    chrome.browserAction.onClicked.addListener(getKeywords);
    

    <强>的manifest.json:

    {
        "manifest_version": 2,
        "name":    "Test Extension",
        "version": "0.0",
    
        "background": {
            "persistent": false,
            "scripts": ["./bg/background.js"]
        },
    
        "browser_action": {
            "default_title": "Test Extension"
        },
    
        "permissions": ["activeTab"]
    }