我试图从我的popup.js中的数据库中获取请求,该请求以对象数组作出响应。我创建了一个for循环,以便迭代遍历所有,但是在每次迭代时我想生成一个新选项卡。我没有问题产生标签。我的问题是,我似乎无法将任何数据传递给他们。我一直在寻找SO,无法找到如何做到这一点??
popup.js:
var button = document.getElementById("button");
button.addEventListener("click", function() {
chrome.runtime.sendMessage({opened: true}, function(response) {
console.log(response.example);
});
});
background.js:
// receives message from popup script
chrome.runtime.onMessage.addListener( function(request, sender, sendResponse) {
if (request) {
// sends response back to popup script
sendResponse({example: "sent from background.js"});
// sends response to content script
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
var data = JSON.parse(xhr.responseText);
for (i = 0; i < data.length; i++) {
console.log(data)
chrome.tabs.create({url: "https://www.google.com/", active: false}, function(tab) {
var tab = tabs[0];
setTimeout(function(){
chrome.tabs.sendMessage(tab.id, data[i], function(response) {
console.log(response);
});
}, 6000);
});
}
}
}
xhr.open('GET', 'https://www.somedata.com', true);
xhr.send(null);
}
});
contentscript.js:
chrome.runtime.onMessage.addListener(function(request,sender,response) {
console.log(request)
console.log(sender)
console.log(response)
});
的manifest.json:
{
"manifest_version": 2,
"name": "demo",
"short_name": "tabs",
"description": "Multiple tabs",
"version": "0.0.1",
"browser_action": {
"default_icon": "img/logo.png",
"128": "128.png",
"default_popup": "popup.html",
"default_title": "Sample"
},
"content_scripts": [{
"matches": ["https://www.google.com/*"],
"js": ["js/contentscript.js"]
}],
"permissions": [
"storage",
"tabs",
"http://*/*",
"https://*/*"
]
}
答案 0 :(得分:0)
问题是,当创建新选项卡时,弹出窗口会在执行回调之前消失。当另一个选项卡变为活动状态时,弹出窗口会自动关闭,当关闭时,弹出窗口将停止执解决此问题的最简单方法是不激活新标签:
chrome.tabs.create({url: "http://www.google.com/", active: false}, function(tab){
chrome.tabs.sendMessage(tab.id, message, function(response) {});
});
虽然您也可以将此功能移至后台页面,但如果非活动选项卡对用户来说很奇怪。不是在popup.js中创建选项卡,而是使用chrome.runtime.sendMessage(传递任何相关数据)向背景页面发送消息,并将监听器放在创建选项卡的后台页面中。 (大部分都是你已经拥有的相同代码,只是四处移动。)
编辑:好的,我发现了其他问题。弹出窗口在附加内容脚本中的消息侦听器之前发送消息,因此它不会接收消息。最简单的解决方法是在消息发送中添加一个计时器:
setTimeout(function(){
chrome.tabs.sendMessage(tab.id, message, function(response) {});
} , 600); //600 works on my computer
这不是一个好的解决方案;只是证明问题是时间的证明。为了更可靠地解决这个问题,我认为你必须有一个更复杂的事情,即contentcript.js消息popup.js在完成加载时,popup.js使用tab.ids或者某些东西来关联加载包含数据数组中元素的页面,并将相应的数据作为对contentscript.js
的响应发送第二次编辑:另一个问题是for循环。因为它是异步的,所以当调用chrome.tabs.create的回调时,循环很久以前就结束了,并且i = data.length(就像循环结束时那样)。因此,您无法将数据[i]作为消息传递,因为数据[data.length]未定义。你可以用这样的递归调用替换它:
background.js:
var data = ["x", "y"]; //just test data. make sure "data" has global scope
chrome.runtime.onMessage.addListener(
function(message, sender, sendResponse) { //from popup.js
createTab(0);
}
);
function createTab(i){
if (i == data.length){return;} //this ends the loop
chrome.tabs.create({url: "https://www.google.com/",
active: false}, function(tab) {
setTimeout(function(){
chrome.tabs.sendMessage(tab.id,data[i], function(response) {}); //to script
createTab(i+1); //this calls the next iteration of the loop
}, 1000);
});
}