我的chrome扩展程序中有一些代码连续多次调用chrome.tabs.insertCSS()
(由于用户选择了可选样式,因此需要)。问题不在于代码不起作用,而是 工作,但我仍然在控制台中收到错误:Attempting to use a disconnected port object
。在相关代码中,我使用chrome.tabs.connect()
,所以我认为可以通过已经连接的端口发送该消息来解决这个问题,但我找不到办法来做到这一点。
我假设chrome.tabs.insertCSS()
使用了下面的消息,因此有理由认为应该有一种方法让它使用已经在使用的端口。
我的问题是:是否可以告诉chrome.tabs.insertCSS
方法使用已存在的开放端口而不是打开另一个端口?如果没有,将多个css / script文件动态加载到我的后台页面的选项卡中的最有效/最常用的方法是什么?
我的背景页:
function setUpListener() {
chrome.runtime.onMessage.addListener(function (msg, sender, respond) {
if (msg["injectCss"]) {
var port = chrome.tabs.connect(sender.tab.id, { name: "injection" });
port.postMessage({ beginInject: msg.injectCss.files.length });
injectCss(port, sender.tab.id, msg.injectCss.files, 0, function (port) {
port.postMessage({ endInject: true });
port.disconnect();
respond();
});
}
return true;
});
}
function injectCss(port, tab, files, index, callback) {
// TODO: try getting/compiling all .css files instead
chrome.tabs.insertCSS(tab, { file: files[index++], runAt: "document_start" }, function () {
if (index > files.length)
return callback(port);
return injectCss(port, tab, files, index, callback);
});
}
编辑:我还考虑将所有必要的CSS编译到一个文件中,而不是多次调用insertCSS
,但我似乎无法找到如何获取我的后台脚本中的那些文件的内容。
答案 0 :(得分:1)
在没有看到与您使用消息传递API相关的所有代码的情况下,我无法具体说明您正在观察的“断开端口”错误。您可能在调用异步injectCss
方法之前关闭端口(通过调用.disconnect()
或卸载页面)。
您当前插入多个CSS文件的方式是可以的,但我会将index > files.length
检查放在insertCss
函数的顶部,以确保在未定义样式表时调用回调:
function injectCss(port, tab, files, index, callback) {
if (index > files.length) {
callback(port);
} else {
chrome.tabs.insertCSS(tab, { file: files[index] }, function () {
injectCss(port, tab, files, index + 1, callback);
});
}
}
关于你的第二个问题(如何连接所有CSS文件),在插入之前:这可以通过多个XMLHttpRequest
调用轻松实现(见下文)。我不明白你为什么要使用这个方法,多次调用insertCSS
同样有效,并且优于下一个方法:如果一个文件是无效的CSS(例如因为缺少大括号) ),当您使用多个chrome.tabs.insertCSS
来电时,其他文件不会受到影响。
function injectCss(port, tab, files, callback) {
var allCss = new Array(files.length);
var tasksToGo = files.length;
if (tasksToGo === 0) {
callback();
return;
}
files.forEach(function(file, index) {
var x = new XMLHttpRequest();
x.open('GET', chrome.runtime.getURL(file));
x.onload = function() {
allCss[index] = x.responseText;
if (--tasksToGo === 0) {
chrome.tabs.insertCSS(tab.id, {
code: allCss.join('\n')
}, callback);
};
};
x.onerror = function() {
// TODO: What if a file is missing?
};
x.send();
});
}