我正在编写一个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。
答案 0 :(得分:1)
这是由于 chrome.tabs.executeScript()的异步性质。您无法从get_keywords
函数返回关键字 - 实际上您可以返回空keywords
数组,但在函数退出之前不会填充它。
(大多数 chrome。* API都是异步的,因此您必须调整整个扩展“样式”以符合此要求。)
那么,会发生什么?
这是执行顺序:
keywords
数组(var keywords = [];
)。executeScript
被称为在后台启动一些非常有用的东西。(function(keywords) {...})(keywords)
,返回并注册一个回调(绑定到仍为空的keywords
数组)。每次注入和执行结束时都会调用回调函数。executeScript
返回(请注意,还没有执行回调 - 仍然在后台执行操作,即注入和执行JS)。console.log(keywords);
记录(仍为空)keywords
数组。keywords
数组(return keywords;
)。keywords
数组。如果激活断点,则在到达步骤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"]
}