问题
My background script should open an URL and wait for it to load completely, so the content script's listener is ready (Am i right with this?). Then it should send the message "newURLvisited" to the content script.
The content script receives the message and gets all links from the website and clicks on one (for example index 10). Normally the content script would activate itself by doing so, because my manifest.json matches all urls (which is necessary for me).
I wanted to fix this problem by calling the content script only when the background script sends the message "newURLcreated". When a link is clicked by the content script, the message "newURLcreated" is send, but this is not the wanted behaviour.
So how can i wait for the content script's listener to load and then send messages to it without having my problem?
I know that i am checking 'load' and tabs.onUpdated, which might not be necessary. I was experimenting with them.
background.js:
chrome.windows.onCreated.addListener(
chrome.tabs.update({url:"https://stackoverflow.com/"});
});
window.addEventListener('load', function(event) {
chrome.tabs.onUpdated.addListener(function (tabId, changeInfo, tab) {
if (changeInfo.status == 'complete') {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
chrome.tabs.sendMessage(tabs[0].id, {txt: "newURLvisited"}, function(response) {});
});
}
});
});
content.js:
chrome.runtime.onMessage.addListener(gotMessage);
function gotMessage(message) {
if (message.txt === "newURLvisited") {
var allLinks = document.getElementsByTagName("a");
}
allLinks[10].click();
}
回答1:
In onUpdated callback you need to check if the updated tab is actually the one you've updated manually. However I'd like to suggest a much simpler overall approach:
- remove "content_scripts" section from manifest.json
- run the content script programmatically.
chrome.tabs.update({url: 'https://stackoverflow.com/'}, tab => {
chrome.tabs.executeScript(tab.id, {file: 'content.js'}, ([results]) => {
console.log(results);
});
});
content.js:
// do something
// ...............
// return some data to executeScript
// (only simple types like strings/numbers or arrays/objects consisting of simple types)
var results = [...document.links].map(el => el.href);
results;
The last line will transfer the array of URLs to executeScript's callback.
来源:https://stackoverflow.com/questions/59295317/how-to-wait-for-content-script-listener-to-load-after-background-script-opens-ur