I know it may sound very strange, but I need to know if there is any active/running javascript in the page.
I am in situation in which I have to run my javascript/jquery code after everything on the page is rendered and all other scripts have finished.
Is it possible to detect this?
EDIT:
Thank you all for the answers. Unfortunately, I was not able to find a solution, because I have no full control of what is going on the page.
Even, I was able to put my javascript in the end of the page, I think it will not be solution again. The reason is that when the page is rendering a function is triggered, it calls other functions and they calls other and so on. As a result, some of the data is incorrect and that's why i need to run my code to correct it.
I use setTimeout with 2 seconds to ensure that my code will be executed last, but this is ugly...
So, thank you all, but this is more problem with the system, not the js.
I know it may sound very strange, but I need to know if there is any active/running javascript in the page.
I am in situation in which I have to run my javascript/jquery code after everything on the page is rendered and all other scripts have finished.
Is it possible to detect this?
EDIT:
Thank you all for the answers. Unfortunately, I was not able to find a solution, because I have no full control of what is going on the page.
Even, I was able to put my javascript in the end of the page, I think it will not be solution again. The reason is that when the page is rendering a function is triggered, it calls other functions and they calls other and so on. As a result, some of the data is incorrect and that's why i need to run my code to correct it.
I use setTimeout with 2 seconds to ensure that my code will be executed last, but this is ugly...
So, thank you all, but this is more problem with the system, not the js.
Share Improve this question edited Mar 6, 2014 at 23:00 tshepang 12.5k25 gold badges97 silver badges139 bronze badges asked Jan 9, 2012 at 14:41 gotqngotqn 43.6k46 gold badges165 silver badges254 bronze badges 8- @Boomer I need to do this cross-browser. – gotqn Commented Jan 9, 2012 at 14:44
- This may help: stackoverflow.com/questions/3283576/… – Diodeus - James MacFarlane Commented Jan 9, 2012 at 14:45
- What do you mean by finished? Do you mean when all scripts have finished loading? If not, there is no way to determine whether a script has completed since scripts are entitled to subscribe to non-deterministic events (eg user input) and then run execute some code in response to this event. – Rich O'Kelly Commented Jan 9, 2012 at 14:46
- fast checks would be to press F12 to open the developer's tool. look for a script section. that would be ur javascript running – Boomer Commented Jan 9, 2012 at 14:47
- In $(document).ready(function () { begin to work after all your elements are created but rendering is an another story. As far as i know you can't know when the browser finished rendering the images. – Kemal Can Kara Commented Jan 9, 2012 at 14:49
3 Answers
Reset to default 15JavaScript on web browsers is single-threaded (barring the use of web workers), so if your JavaScript code is running, by definition no other JavaScript code is running.*
To try to ensure that your script occurs after all other JavaScript on the page has been downloaded and evaluated and after all rendering has occurred, some suggestions:
- Put the script tag for your code at the very end of the file.
- Use the
defer
andasync
attributes on the tag (they'll be ignored by browsers that don't support them, but the goal is to make yours the last as much as we can). - Hook the
window
load
event via a DOM2 style hookup (e.g.,addEventListener
on browsers with standards support, orattachEvent
on older IE versions). - In the
load
event, schedule your code to run after asetTimeout
with a delay of 0ms (it won't really be zero, it'll be slightly longer).
So, the script
tag:
<script async defer src="yourfile.js"></script>
...and yourfile.js
:
(function() {
if (window.addEventListener) {
window.addEventListener("load", loadHandler, false);
}
else if (window.attachEvent) {
window.attachEvent("onload", loadHandler);
}
else {
window.onload = loadHandler; // Or you may want to leave this off and just not support REALLY old browsers
}
function loadHandler() {
setTimeout(doMyStuff, 0);
}
function doMyStuff() {
// Your stuff here. All images in the original markup are guaranteed
// to have been loaded (or failed) by the `load` event, and you know
// that other handlers for the `load` event have now been fired since
// we yielded back from our `load` handler
}
})();
That doesn't mean that other code won't have scheduled itself to run later (via setTimeout
, for instance, just like we did above but with a longer timeout), though.
So there are some things you can do to try to be last, but I don't believe there's any way to actually guarantee it without having full control of the page and the scripts running on it (I take it from the question that you don't).
(* There are some edge cases where the thread can be suspended in one place and then allow other code to run in another place [for instance, when an ajax call completes while an alert
message is being shown, some browsers fire the ajax handler even though another function is waiting on the alert
to be dismissed], but they're edge cases and there's still only one thing actively being done at a time.)
There is no definitive way to do this because you can't really know what the latest is that other scripts have scheduled themselves to run. You will have to decide what you want to target.
- You can try to run your script after anything else that may be running when the DOM is loaded.
- You can try to run your script after anything else that may be running when the page is fully loaded (including images).
There is no reliable, cross-browser way to know which of these events, the scripts in the page are using.
In either case, you hook the appropriate event and then use a setTimeout()
to try to run your script after anything else that is watching those events.
So, for example, if you decided to wait until the whole page (including images) was loaded and wanted to try to make your script run after anything else that was waiting for the same event, you would do something like this:
window.addEventListener("load", function() {
setTimeout(function() {
// put your code here
}, 1);
}, false);
You would have to use attachEvent()
for older versions of IE.
When using this method, you don't have to worry about where your scripts are loaded in the page relative to other scripts in the page since this schedules your script to run at a particular time after a particular event.
A way to know when multiple functions have all finished executing
This can be useful if you have to wait multiple API calls or initialisation functions
let processRemining = 0;
async function f1() {
processRemining++
await myAsyncFunction()
processFinished()
}
async function f2() {
processRemining++
await myAsyncFunction2()
processFinished()
}
function processFinished() {
processRemining--
setTimeout(() => { // this is not needed is all the functions are async
if (processRemining === 0) {
// Code to execute when all the functions have finished executing
}
}, 1)
}
f1()
f2()
I often couple it with a freezeClic function to prevent users to interact with the page when there is a script that is still waiting an ajax / async response (and optionnaly display a preloader icon or screen).