Reputation: 1655
First time creating a Chrome extension, finding it a bit overwhelming.
I'm trying to create a plugin to extract review data from a website and store it in a text file. I want to be able to click the plugin button to start the downloads, and then the plugin should navigate to each review on the website using the Next Review button provided on the page, until it reaches the last review.
Each page takes some time to load, so I need to wait for the page to load before I can call the function that extracts the info and causes the page to move forward.
I originally tried using timers, but that obviously gives inconsistent behavior across systems, so I am now trying to use the chrome.webNavigation
/chrome.tabs
APIs.
Here's where I'm facing an issue. Neither chrome.webNavigation.onDOMContentLoaded
nor chrome.webNavigation.onCompleted
get fired if I'm using a link within the page to navigate to another page. They are only getting triggered if I navigate to a page by manually entering the url, or if I reload the page.
So I tried using the chrome.tabs.onUpdated
event. This successfully recognizes that I have clicked on a link, but it gets triggered the instant I click the button. It does not wait for the DOM content to load. I need a way to delay this (without using timers) so that it fires after the page content loads
Here's an excerpt of my background script:
chrome.webNavigation.onDOMContentLoaded.addListener((tab) => {
if (tab.frameId === 0)
console.log("webNavigation DOMContentLoaded")
})
chrome.webNavigation.onCompleted.addListener((tab) => {
if (tab.frameId === 0)
console.log("webNavigation Content Loaded")
})
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
let msg = {
txt : "ContentLoaded"
}
if (changeInfo.status == 'complete' && tab.status == 'complete') {
console.log('tabs ContentLoaded')
chrome.tabs.sendMessage(tab.id, msg)
}
})
I may be interpreting this incorrectly, but I was under the impression that the TabStatus (changeInfo.status) would show 'complete' when the page finishes loading (sort of like the 'load' event). Obviously, that isn't happening. If someone could also explain how it actually works, that'd be brilliant.
So, to summarize: I need a way for the Chrome plugin to realize that I've navigated to another page using a link, and it should fire an event only when the page content finishes loading.
Upvotes: 4
Views: 1841
Reputation: 129
I struggled with this issue as well - I was using chrome.tabs.onUpdated
to listen for the completed
state of the tab. Then I would send a message to the content script (that wasn't loaded yet), and an error would be thrown.
To get around this, I used the scripting API to load in a JS file that ran my code. This only worked because the code I wanted to run at the onUpdated
event didn't require any context from the original content scripts. Heres an example:
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
if (changeInfo.status == "complete" && tab.url) {
// other checks for my use case here, then:
chrome.scripting.executeScript({
target: { tabId: tab.id },
files: ['js/scripts/listenForSubscription.js']
})
}
});
Again I'd like to reiterate that this only works because all listenForSubscription.js
does is bind an event listener to an element on the DOM, so it doesn't need to interface with any objects or variables in the original content script. But this was a nice workaround to get rid of those annoying message-passing errors. Hope this helps
Upvotes: -1