This question already has answers here:
How to make JavaScript execute after page load?
(25 answers)
Closed 1 year ago.
I am using following code to execute some statements after page load.
<script type="text/javascript">
window.onload = function () {
newInvite();
document.ag.src="b.jpg";
}
</script>
But this code does not work properly. The function is called even if some images or elements are loading. What I want is to call the function the the page is loaded completely.
this may work for you :
document.addEventListener('DOMContentLoaded', function() {
// your code here
}, false);
or
if your comfort with jquery,
$(document).ready(function(){
// your code
});
$(document).ready() fires on DOMContentLoaded, but this event is not being fired consistently among browsers. This is why jQuery will most probably implement some heavy workarounds to support all the browsers. And this will make it very difficult to "exactly" simulate the behavior using plain Javascript (but not impossible of course).
as Jeffrey Sweeney and J Torres suggested, i think its better to have a setTimeout function, before firing the function like below :
setTimeout(function(){
//your code here
}, 3000);
JavaScript
document.addEventListener('readystatechange', event => {
// When HTML/DOM elements are ready:
if (event.target.readyState === "interactive") { //does same as: ..addEventListener("DOMContentLoaded"..
alert("hi 1");
}
// When window loaded ( external resources are loaded too- `css`,`src`, etc...)
if (event.target.readyState === "complete") {
alert("hi 2");
}
});
same for jQuery:
$(document).ready(function() { //same as: $(function() {
alert("hi 1");
});
$(window).load(function() {
alert("hi 2");
});
NOTE: - Don't use the below markup ( because it overwrites other same-kind declarations ) :
document.onreadystatechange = ...
I'm little bit confuse that what you means by page load completed, "DOM Load" or "Content Load" as well? In a html page load can fire event after two type event.
DOM load: Which ensure the entire DOM tree loaded start to end. But not ensure load the reference content. Suppose you added images by the img tags, so this event ensure that all the img loaded but no the images properly loaded or not. To get this event you should write following way:
document.addEventListener('DOMContentLoaded', function() {
// your code here
}, false);
Or using jQuery:
$(document).ready(function(){
// your code
});
After DOM and Content Load: Which indicate the the DOM and Content load as well. It will ensure not only img tag it will ensure also all images or other relative content loaded. To get this event you should write following way:
window.addEventListener('load', function() {...})
Or using jQuery:
$(window).on('load', function() {
console.log('All assets are loaded')
})
If you can use jQuery, look at load. You could then set your function to run after your element finishes loading.
For example, consider a page with a simple image:
<img src="book.png" alt="Book" id="book" />
The event handler can be bound to the image:
$('#book').load(function() {
// Handler for .load() called.
});
If you need all elements on the current window to load, you can use
$(window).load(function () {
// run code
});
If you cannot use jQuery, the plain Javascript code is essentially the same amount of (if not less) code:
window.onload = function() {
// run code
};
If you wanna call a js function in your html page use onload event. The onload event occurs when the user agent finishes loading a window or all frames within a FRAMESET. This attribute may be used with BODY and FRAMESET elements.
<body onload="callFunction();">
....
</body>
You're best bet as far as I know is to use
window.addEventListener('load', function() {
console.log('All assets loaded')
});
The #1 answer of using the DOMContentLoaded event is a step backwards since the DOM will load before all assets load.
Other answers recommend setTimeout which I would strongly oppose since it is completely subjective to the client's device performance and network connection speed. If someone is on a slow network and/or has a slow cpu, a page could take several to dozens of seconds to load, thus you could not predict how much time setTimeout will need.
As for readystatechange, it fires whenever readyState changes which according to MDN will still be before the load event.
Complete
The state indicates that the load event is about to fire.
This way you can handle the both cases - if the page is already loaded or not:
document.onreadystatechange = function(){
if (document.readyState === "complete") {
myFunction();
}
else {
window.onload = function () {
myFunction();
};
};
}
you can try like this without using jquery
window.addEventListener("load", afterLoaded,false);
function afterLoaded(){
alert("after load")
}
Alternatively you can try below.
$(window).bind("load", function() {
// code here });
This works in all the case. This will trigger only when the entire page is loaded.
window.onload = () => {
// run in onload
setTimeout(() => {
// onload finished.
// and execute some code here like stat performance.
}, 10)
}
If you're already using jQuery, you could try this:
$(window).bind("load", function() {
// code here
});
I can tell you that the best answer I found is to put a "driver" script just after the </body> command. It is the easiest and, probably, more universal than some of the solutions, above.
The plan: On my page is a table. I write the page with the table out to the browser, then sort it with JS. The user can resort it by clicking column headers.
After the table is ended a </tbody> command, and the body is ended, I use the following line to invoke the sorting JS to sort the table by column 3. I got the sorting script off of the web so it is not reproduced here. For at least the next year, you can see this in operation, including the JS, at static29.ILikeTheInternet.com. Click "here" at the bottom of the page. That will bring up another page with the table and scripts. You can see it put up the data then quickly sort it. I need to speed it up a little but the basics are there now.
</tbody></body><script type='text/javascript'>sortNum(3);</script></html>
MakerMikey
I tend to use the following pattern to check for the document to complete loading. The function returns a Promise (if you need to support IE, include the polyfill) that resolves once the document completes loading. It uses setInterval underneath because a similar implementation with setTimeout could result in a very deep stack.
function getDocReadyPromise()
{
function promiseDocReady(resolve)
{
function checkDocReady()
{
if (document.readyState === "complete")
{
clearInterval(intervalDocReady);
resolve();
}
}
var intervalDocReady = setInterval(checkDocReady, 10);
}
return new Promise(promiseDocReady);
}
Of course, if you don't have to support IE:
const getDocReadyPromise = () =>
{
const promiseDocReady = (resolve) =>
{
const checkDocReady = () =>
((document.readyState === "complete") && (clearInterval(intervalDocReady) || resolve()));
let intervalDocReady = setInterval(checkDocReady, 10);
}
return new Promise(promiseDocReady);
}
With that function, you can do the following:
getDocReadyPromise().then(whatIveBeenWaitingToDo);
call a function after complete page load set time out
setTimeout(function() {
var val = $('.GridStyle tr:nth-child(2) td:nth-child(4)').text();
for(var i, j = 0; i = ddl2.options[j]; j++) {
if(i.text == val) {
ddl2.selectedIndex = i.index;
break;
}
}
}, 1000);
Try this jQuery:
$(function() {
// Handler for .ready() called.
});
Put your script after the completion of body tag...it works...
Related
I put an event javascript function inside the HTML body section of the page.
<script type="text/javascript">
function CookiebotCallback_OnAccept() {
window.location.reload(true);
if (Cookiebot.consent.statistics)
{
}
}
</script>
This script causes an infinite refresh because the function run every time the page is loaded. What can I do to make this function only run when it is called and not automatically every page load?
No need to deal with manipulating cookies, or any other hacky solutions. JavaScript offers a few native event listeners for verifying that the document has been successfully loaded. Essentially your three options are:
Inline HTML example
1. <body onload='fooBar()'>
Native DOM events that can be invoked within an HTML snippet,
or more preferably, within there own parent function to offer
more fine grained control over invocation.
2. document.onload = ()=>
3. window.onload = ()=>
i.e:
const foo = () => document.onload
const bar = () => window.onload
Invoking them anywhere within you code base as necesary without
rigidly coupling your JavaScript code within your HTML
The preferred method is window.onload as the document isn't completely honest about when it's been loaded.
Following the logic you have above using the inline approach, here's a working alternative:
// Add the following HTML immediately after your opening `body` tag.
// This ensures no competing JS scripts can run before the one we have
// here.
<script type="text/javascript">
(() => {
const runMeAfterPageLoad = () =>
Cookiebot.consent.statistics ? // If true logic here : null
if (window.addEventListener) {
window.addEventListener('load', runMeAfterPageLoad, false)
}
else if (window.attachEvent) {
window.attachEvent('onload', runMeAfterPageLoad)
}
else window.onload = runMeAfterPageLoad
})()
</script>
my solution is creating a flag variable in localStorage or sessionStorage, then check if has the variable already, skip calling reload.
<script type="text/javascript">
function CookiebotCallback_OnAccept() {
if(!sessionStorage.getItem('isReloaded')) {
sessionStorage.setItem('isReloaded', true);
window.location.reload(true);
if (Cookiebot.consent.statistics)
{
}
}
}
</script>
// you can also clear the variable to trigger the reload again.
// By: sessionStorage.removeItem('isReloaded');
// Note: the sessionStorage will be cleared each time you close the browser,
// while localStorage is only by uninstalled the browser or manually.
i am trying to get the first ready state of the DOM. the second, third, etc is not interesting me, but the first one. is there any trick to get the first ready state of DOM?
$(document).ready(function() {
// is it the first ready state?
});
There are 4 readyState possible values:
uninitialized - Has not started loading yet
loading - Is loading
interactive - Has loaded enough and the user can interact with it
complete - Fully loaded
To see it's value use this code:
document.onreadystatechange = function () {
if (document.readyState === YourChoice) {
// ...
}
}
I could not catch the uninitialized readyState. (but why should I need it?)
If you need a listener for complete load of the DOM, use:
document.addEventListener('DOMContentLoaded', YourListener);
or
document.addEventListener('load', YourListener);
or even
window.onload = YourListener;
for jquery:
$(document).on("DOMContentLoaded", function() { });
or
$(document).on("load", function() { });
or
$(window).on("load", function() { });
Ah, you're using jQuery. Have a look at the docs: There is only one ready event! I will never fire multiple times. Internally, this is even handled with a Promise, so it cannot fire multiple times.
I'm writing a Javascript script.
This script will probably be loaded asynchronously (AMD format).
In this script, I'd like to do nothing important until the window.load event was fired.
So I listen to the window "load" event.
But if the script is loaded after window.load event... how can I know window.load was already fired?
And of course I don't want to add something in any other scripts (they are all loaded async, the problem is the same) :)
Edit :
Imagine an HTML doc with no Javascript in it at all.
Than someone insert in this doc a tag, and this script tag loads my Javascript file.
This will execute my script.
How this script can know if window.load was already fired ?
No jQuery, not any script in the HTML doc before mine.
Is it possible to know ??
I found the window.document.readystate property. This property is for document "ready" event I guess, not for window "load".
Is there anything similar for window "load" event ?
The easiest solution might be checking for document.readyState == 'complete', see http://www.w3schools.com/jsref/prop_doc_readystate.asp
Quick Answer
To quickly answer the question's title:
document.readyState === 'complete'
Deeper Example
Below is a nice helper if you want to call code upon a window load, while still handling the case where the window may have already loaded by the time your code runs.
function winLoad(callback) {
if (document.readyState === 'complete') {
callback();
} else {
window.addEventListener("load", callback);
}
}
winLoad(function() {
console.log('Window is loaded');
});
Note: code snippets on here actually don't run in the same window context so document.readyState === 'complete' actually evaluates to false when you run this. If you put the same into your console right now for this window it should evaluate as true.
See also: What is the non-jQuery equivalent of '$(document).ready()'?
Handling the Edge Case from #IgorBykov via Comments
Igor brought up an interesting issue in the comments, which the following code can try to handle given a best-effort-timeout.
The problem is that the document.readyState can be complete before the load event fires. I'm not certain what potential problems this may cause.
Some Documentation About the Flow and Event Firing
https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState
Complete: The state indicates that the load event is about to fire.
https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event
Gives a live example of event firing ie:
readyState: interactive
Event Fired: DOMContentLoaded
readyState: complete
Event Fired: load
There's a brief moment where the readyState may be complete before load fires. I'm not sure what issues you may run into during this period.
The below code registers the load event listener, and sets a timeout to check the readyState. By default it will wait 200ms before checking the readyState. If the load event fires before the timeout we make sure to prevent firing the callback again. If we get to the end of the timeout and load wasn't fired we check the readyState and make sure to avoid a case where the load event could potentially still fire at a later time.
Depending on what you're trying to accomplish you may want to run the load callback no matter what (remove the if (!called) { check). In your callback you might want to wrap potential code in a try/catch statement or check for something that you can gate the execution on so that when it calls twice it only performs the work when everything is available that you expect.
function winLoad(callback, timeout = 200) {
let called = false;
window.addEventListener("load", () => {
if (!called) {
called = true;
callback();
}
});
setTimeout(() => {
if (!called && document.readyState === 'complete') {
called = true;
callback();
}
}, timeout);
}
winLoad(function() {
console.log('Window is loaded');
});
Browser navigation performance loadEventEnd metric can be used to determinate if load event was triggered:
let navData = window.performance.getEntriesByType("navigation");
if (navData.length > 0 && navData[0].loadEventEnd > 0)
{
console.log('Document is loaded');
} else {
console.log('Document is not loaded');
}
Based on #CTS_AE's approach, I have put together a solution for envrionments where:
window.addEventListener('load', activateMyFunction); and
window.addEventListener('DOMContentLoaded', activateMyFunction);
don't work.
It requires a single character substitution (eg. from
window.addEventListener('load', activateMyFunction);
to
window_addEventListener('load', activateMyFunction);)
The function window_addEventListener() looks like this:
const window_addEventListener = (eventName, callback, useCapture = false) => {
if ((document.readyState === 'interactive') || (document.readyState === 'complete')) {
callback();
}
}
If you don't want to use jQuery, the logic it uses is:
if( !document.body )
setTimeout( checkAgain, 1 );
So between the windows loaded event and checking if the body property of the document is available, you can check if the DOM is ready
Easy method:
window.onload = (event) => {
console.log('page is fully loaded');
};
You can find other methods from resources here.
what about overriding window.load?
window._load = window.load;
window.load = function(){
window.loaded = true;
window._load();
}
Then check for
if (window.loaded != undefined && window.loaded == true){
//do stuff
}
I need to be sure that a certain script within a page is executed as last.
I thought of using JQuery
$(document).ready( ... )
but if there are more functions of this type, which is actually executed last?
There are many ways to delay the execution of a script.
There is no way to programatically detect all of them.
For a reliable solution you would have to reverse engine the code of each page you care about, figure out what it is doing (and when) and write your delay script specifically for that page. (For a value of "reliable" equal to "until they change the page").
$(document).ready( ... )
is not executed last. The last function executed ( so, after document ready ) is the one(s) from <body onload>.
Example : <body onload="myJSfunction();">
Here, the javascript myJSfunction is executed at the end, after $(document).ready( ... ).
This depends on the order in which you have registered them.
E.g:
$(document).ready( function() { alert("first"); });
$(document).ready( function() { alert("second"); });
$(document).ready( function() { alert("third"); });
would alert "first" then "second" then "third"
So adding a <script> to the bottom of your page with an $(document).ready( yourfunction ); would suffice.
Theoretically you can do something like this:
// Form array of functions which sould be called with according order
$.readyArray = [function () { ... }, function () { ... }, function () { ... }, ...];
// just execute them in this order when onready event
$(document).ready(function() {
for (var i = 0; i < $.readyArray.length; i++) {
//apply, calls function in current context and pass arguments object
$.readyArray[i].apply(this,[arguments]);
}
});
If refactoring (as Quentin suggested) is not an option (e.g. you are updating a just part of a framework or a product), you can use four approaches, which should give you a good chance achieving what you need. See the following snippets with jQuery:
(1) Wait until 'document' is ready
By document is meant the visible DOM. The script will fire when all it should be rendered really rendered is.
$(document).ready(function() {
console.log('Document is ready.');
});
(2) Wait until top-level JS (Root) 'window' object is ready
The full root object can (will) be ready some time after the DOM is ready.
$(window).ready(function() {
console.log('Window is ready.');
});
(3) Wait until 'window' is fully loaded using .bind
This fires immediately after 'window' is ready, so your script can act on objects (elements) rendered during $(window).ready() above.
$(window).bind("load", function() {
console.log('Window bind is ready.');
});
(4) Wait until Ajax calls are completed
This is as far as you can go - the script will fire when 'window' is ready, loaded, all the code run and all the Ajax actions are completed. Unfortunately, since one Ajax can call another one, it can fire several times during the page load.
$(window).ajaxComplete(function() {
console.log('Window bind is ready, Ajax finished.');
}
In simple Javascript solution, you could call the javascript function at end of your HTML document inside the script tag. This works well when you are not using jQuery.
In case of jQuery you could use load method.The load event is sent to an element when it and all sub-elements have been completely loaded.
For more info look at
http://api.jquery.com/load-event/
Try this,
$(window).bind("load", function() {
//code here
});
I have a script that is being inserted dynamically via another script. The code in that script is wrapped inside the $(window).load() event because it requires the images on the page to have all loaded. In some browsers it works fine, but in others it seems not to fire because the page has already finished loading by the time the code is run.
Is there any way to check and see whether the page has already finished loading - either via jQuery or JavaScript? (including images)
In this situation, I don't have access to the onload event of the original document (aside from altering it via the loaded script - but that would seem to present the same problem).
Any ideas/solutions/advice would be greatly appreciated!
You could try setting up a handler that's invoked via a timeout that will check the images to see if their properties are available. Clear the timer in the load event handler so if the load event occurs first, the timer won't fire. If the properties aren't available, then the load event hasn't fired yet and you know that your handler will eventually be invoked. If they are, then you know that the load event occurred before your handler was set and you can simply proceed.
Pseudocode
var timer = null;
$(function() {
$(window).load( function() {
if (timer) {
clearTimeout(timer);
timer = null;
}
process();
});
timer = setTimeout( function() {
if (checkAvailable())
process();
}
}, 10*1000 ); // waits 10 seconds before checking
});
function checkAvailable()
{
var available = true;
$('img').each( function() {
try {
if (this.height == 0) {
available = false;
return false;
}
}
catch (e) {
available = false;
return false;
}
});
return available;
}
function process() {
... do the real work here
}
I wrote a plugin that may be of some use: http://plugins.jquery.com/project/window-loaded
I think your problem would resolve itself if you'd use $(document).ready instead of $(window).load - see the jquery documentation.
You guys should read this:
http://web.enavu.com/daily-tip/daily-tip-difference-between-document-ready-and-window-load-in-jquery/
Don't know if this is what you are after, but have you tried(?):
$(document).ready(function(){
...
});
http://docs.jquery.com/Events/ready#fn