Reputation: 79
Look at screenshot:
Extension's content script
console.log( targetDiv ) // output: undefined
Google Chrome console
console.log( targetDiv ) // output: targetDiv
How is that possible? The other 'normal' elements are printed out in both cases. Can you explain me this magic half-child element?
UPDATE: this div created dynamicly setInterval fixes problem!
Upvotes: 1
Views: 3269
Reputation: 11
The polling answer by dhilt indeed does work, for pages using script loading to inject DOM (e.g. if they're using some web frameworks), you'll need to poll to retrieve results.
Just adding a bit on how you could use Promises to asynchronously compute the value of something you need to do:
const yourFunction = async (
...
): Promise<ReturnValueType> => {
let POLL_COUNT = 20;
let POLL_INTERVAL_SEC = MAX_DURATION / POLL_COUNT;
let pollingTries = 0;
let result: ReturnValueType;
return new Promise((resolve, reject) => {
const timer = setInterval(() => {
if (pollingTries >= POLL_COUNT) {
console.log("Max poll tries reached...");
clearTimeout(timer);
reject(new Error("Failed to retrieve result within specified duration"));
}
pollingTries++;
console.log(`Running poll... #${pollingTries}`);
// core functionality here
if (!result) {
console.log(`No results found yet!`);
} else {
// Stop interval if results are found
clearTimeout(timer);
resolve(results);
}
}, POLL_INTERVAL_SEC * MS_IN_SECONDS);
});
};
Upvotes: 0
Reputation: 544
A simple solution to this can be to run the script after the page is fully loaded. Something like:
window.onload = function() {
// run script
};
should work fine.
However, note that the script will run after all images and css are completely loaded and parsed.
Upvotes: 0
Reputation: 20744
You need to make sure that your script is loaded after that element is in DOM. Try to debug it, set up the breakpoint on your console.log(targetDiv)
and investigate DOM manually. This element rendering may be delayed by some inner script for example. In that case you may implement a kind of polling process to detect this element in time:
const timer = setInterval(() => {
const myElement = document.getElementById('my-element');
if(myElement) {
clearTimeout(timer);
processMyElement(myElement);
}
}, 150);
instead of just
const myElement = document.getElementById('my-element');
processMyElement(myElement);
Upvotes: 2