I'm executing an external script, using a <script> inside <head>.
Now since the script executes before the page has loaded, I can't access the <body>, among other things. I'd like to execute some JavaScript after the document has been "loaded" (HTML fully downloaded and in-RAM). Are there any events that I can hook onto when my script executes, that will get triggered on page load?
These solutions will work:
As mentioned in comments use defer:
<script src="deferMe.js" defer></script>
or
<body onload="script();">
or
document.onload = function ...
or even
window.onload = function ...
Note that the last option is a better way to go since it is unobstrusive and is considered more standard.
Triggering scripts in the right moment
A quick overview on how to load / run the script at the moment in which they intend to be loaded / executed.
Using "defer"
<script src="script.js" defer></script>
Using defer will trigger after domInteractive (document.readyState = "interactive") and just before "DOMContentLoaded" Event is triggered. If you need to execute the script after all resources (images, scripts) are loaded use "load" event or target one of the document.readyState states. Read further down for more information about those events / states, as well as async and defer attributes corresponding to script fetching and execution timing.
This Boolean attribute is set to indicate to a browser that the script
is meant to be executed after the document has been parsed, but before
firing DOMContentLoaded.
Scripts with the defer attribute will prevent the DOMContentLoaded
event from firing until the script has loaded and finished evaluating.
Resource: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attributes
* See the images at the bottom for feather explanation.
Event Listeners - Keep in mind that loading of the page has more, than one event:
"DOMContentLoaded"
This event is fired when the initial HTML document has been completely loaded and parsed, without waiting for style sheets, images, and subframes to finish loading. At this stage you could programmatically optimize loading of images and CSS based on user device or bandwidth speed.
Executes after DOM is loaded (before images and CSS):
document.addEventListener("DOMContentLoaded", function(){
//....
});
Note: Synchronous JavaScript pauses parsing of the DOM.
If you want the DOM to get parsed as fast as possible after the user requested the page, you could turn your JavaScript asynchronous and optimize loading of style sheets
"load"
A very different event, **load**, should only be used to detect a *fully-loaded page*. It is an incredibly popular mistake to use load where DOMContentLoaded would be much more appropriate, so be cautious.
Executes after everything is loaded and parsed:
document.addEventListener("load", function(){
// ....
});
MDN Resources:
https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded
https://developer.mozilla.org/en-US/docs/Web/Events/load
MDN list of all events:
https://developer.mozilla.org/en-US/docs/Web/Events
Event Listeners with readyStates - Alternative solution (readystatechange):
You can also track document.readystatechange states to trigger script execution.
// Place in header (do not use async or defer)
document.addEventListener('readystatechange', event => {
switch (document.readyState) {
case "loading":
console.log("document.readyState: ", document.readyState,
`- The document is still loading.`
);
break;
case "interactive":
console.log("document.readyState: ", document.readyState,
`- The document has finished loading DOM. `,
`- "DOMContentLoaded" event`
);
break;
case "complete":
console.log("document.readyState: ", document.readyState,
`- The page DOM with Sub-resources are now fully loaded. `,
`- "load" event`
);
break;
}
});
MDN Resources: https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState
Where to place your script (with & without async/defer)?
This is also very important to know where to place your script and how it positions in HTML as well as parameters like defer and async will affects script fetching, execution and HTML blocking.
* On the image below the yellow label “Ready” indicates the moment of ending loading HTML DOM. Then it fires: document.readyState = "interactive" >>> defered scripts >>> DOMContentLoaded event (it's sequential);
If your script uses async or defer read this: https://flaviocopes.com/javascript-async-defer/
And if all of the above points are still to early...
What if you need your script to run after other scripts are run, including those scheduled to run at the very end (e.g. those scheduled for the "load" event)? See Run JavaScript after all window.onload scripts have completed?
What if you need to make sure your script runs after some other script, regardless of when it is run? This answer to the above question has that covered too.
Reasonably portable, non-framework way of having your script set a function to run at load time:
if(window.attachEvent) {
window.attachEvent('onload', yourFunctionName);
} else {
if(window.onload) {
var curronload = window.onload;
var newonload = function(evt) {
curronload(evt);
yourFunctionName(evt);
};
window.onload = newonload;
} else {
window.onload = yourFunctionName;
}
}
You can put a "onload" attribute inside the body
...<body onload="myFunction()">...
Or if you are using jQuery, you can do
$(document).ready(function(){ /*code here*/ })
or
$(window).load(function(){ /*code here*/ })
I hope it answer your question.
Note that the $(window).load will execute after the document is rendered on your page.
If the scripts are loaded within the <head> of the document, then it's possible use the defer attribute in script tag.
Example:
<script src="demo_defer.js" defer></script>
From https://developer.mozilla.org:
defer
This Boolean attribute is set to indicate to a browser that the script
is meant to be executed after the document has been parsed, but before
firing DOMContentLoaded.
This attribute must not be used if the src
attribute is absent (i.e. for inline scripts), in this case it would
have no effect.
To achieve a similar effect for dynamically inserted scripts use
async=false instead. Scripts with the defer attribute will execute in
the order in which they appear in the document.
Here's a script based on deferred js loading after the page is loaded,
<script type="text/javascript">
function downloadJSAtOnload() {
var element = document.createElement("script");
element.src = "deferredfunctions.js";
document.body.appendChild(element);
}
if (window.addEventListener)
window.addEventListener("load", downloadJSAtOnload, false);
else if (window.attachEvent)
window.attachEvent("onload", downloadJSAtOnload);
else window.onload = downloadJSAtOnload;
</script>
Where do I place this?
Paste code in your HTML just before the </body> tag (near the bottom of your HTML file).
What does it do?
This code says wait for the entire document to load, then load the
external file deferredfunctions.js.
Here's an example of the above code - Defer Rendering of JS
I wrote this based on defered loading of javascript pagespeed google concept and also sourced from this article Defer loading javascript
Look at hooking document.onload or in jQuery $(document).load(...).
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 find sometimes on more complex pages that not all the elements have loaded by the time window.onload is fired. If that's the case, add setTimeout before your function to delay is a moment. It's not elegant but it's a simple hack that renders well.
window.onload = function(){ doSomethingCool(); };
becomes...
window.onload = function(){ setTimeout( function(){ doSomethingCool(); }, 1000); };
<script type="text/javascript">
function downloadJSAtOnload() {
var element = document.createElement("script");
element.src = "defer.js";
document.body.appendChild(element);
}
if (window.addEventListener)
window.addEventListener("load", downloadJSAtOnload, false);
else if (window.attachEvent)
window.attachEvent("onload", downloadJSAtOnload);
else window.onload = downloadJSAtOnload;
</script>
http://www.feedthebot.com/pagespeed/defer-loading-javascript.html
Working Fiddle on <body onload="myFunction()">
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function myFunction(){
alert("Page is loaded");
}
</script>
</head>
<body onload="myFunction()">
<h1>Hello World!</h1>
</body>
</html>
If you are using jQuery,
$(function() {...});
is equivalent to
$(document).ready(function () { })
or another short hand:
$().ready(function () { })
See What event does JQuery $function() fire on? and https://api.jquery.com/ready/
document.onreadystatechange = function(){
if(document.readyState === 'complete'){
/*code here*/
}
}
look here: http://msdn.microsoft.com/en-us/library/ie/ms536957(v=vs.85).aspx
Just define <body onload="aFunction()"> that will be called after the page has been loaded. Your code in the script is than enclosed by aFunction() { }.
<body onload="myFunction()">
This code works well.
But window.onload method has various dependencies. So it may not work all the time.
Comparison
In below snippet I collect choosen methods and show their sequence. Remarks
the document.onload (X) is not supported by any modern browser (event is never fired)
if you use <body onload="bodyOnLoad()"> (F) and at the same time window.onload (E) then only first one will be executed (because it override second one)
event handler given in <body onload="..."> (F) is wrapped by additional onload function
document.onreadystatechange (D) not override document .addEventListener('readystatechange'...) (C) probably cecasue onXYZevent-like methods are independent than addEventListener queues (which allows add multiple listeners). Probably nothing happens between execution this two handlers.
all scripts write their timestamp in console - but scripts which also have access to div write their timestamps also in body (click "Full Page" link after script execution to see it).
solutions readystatechange (C,D) are executed multiple times by browser but for different document states:
loading - the document is loading (no fired in snippet)
interactive - the document is parsed, fired before DOMContentLoaded
complete - the document and resources are loaded, fired before body/window onload
<html>
<head>
<script>
// solution A
console.log(`[timestamp: ${Date.now()}] A: Head script`);
// solution B
document.addEventListener("DOMContentLoaded", () => {
print(`[timestamp: ${Date.now()}] B: DOMContentLoaded`);
});
// solution C
document.addEventListener('readystatechange', () => {
print(`[timestamp: ${Date.now()}] C: ReadyState: ${document.readyState}`);
});
// solution D
document.onreadystatechange = s=> {print(`[timestamp: ${Date.now()}] D: document.onreadystatechange ReadyState: ${document.readyState}`)};
// solution E (never executed)
window.onload = () => {
print(`E: <body onload="..."> override this handler`);
};
// solution F
function bodyOnLoad() {
print(`[timestamp: ${Date.now()}] F: <body onload='...'>`);
infoAboutOnLoad(); // additional info
}
// solution X
document.onload = () => {print(`document.onload is never fired`)};
// HELPERS
function print(txt) {
console.log(txt);
if(mydiv) mydiv.innerHTML += txt.replace('<','<').replace('>','>') + '<br>';
}
function infoAboutOnLoad() {
console.log("window.onload (after override):", (''+document.body.onload).replace(/\s+/g,' '));
console.log(`body.onload==window.onload --> ${document.body.onload==window.onload}`);
}
console.log("window.onload (before override):", (''+document.body.onload).replace(/\s+/g,' '));
</script>
</head>
<body onload="bodyOnLoad()">
<div id="mydiv"></div>
<!-- this script must te at the bottom of <body> -->
<script>
// solution G
print(`[timestamp: ${Date.now()}] G: <body> bottom script`);
</script>
</body>
</html>
There is a very good documentation on How to detect if document has loaded using Javascript or Jquery.
Using the native Javascript this can be achieved
if (document.readyState === "complete") {
init();
}
This can also be done inside the interval
var interval = setInterval(function() {
if(document.readyState === 'complete') {
clearInterval(interval);
init();
}
}, 100);
Eg By Mozilla
switch (document.readyState) {
case "loading":
// The document is still loading.
break;
case "interactive":
// The document has finished loading. We can now access the DOM elements.
var span = document.createElement("span");
span.textContent = "A <span> element.";
document.body.appendChild(span);
break;
case "complete":
// The page is fully loaded.
console.log("Page is loaded completely");
break;
}
Using Jquery
To check only if DOM is ready
// A $( document ).ready() block.
$( document ).ready(function() {
console.log( "ready!" );
});
To check if all resources are loaded use window.load
$( window ).load(function() {
console.log( "window loaded" );
});
Use this code with jQuery library, this would work perfectly fine.
$(window).bind("load", function() {
// your javascript event
});
$(window).on("load", function(){ ... });
.ready() works best for me.
$(document).ready(function(){ ... });
.load() will work, but it won't wait till the page is loaded.
jQuery(window).load(function () { ... });
Doesn't work for me, breaks the next-to inline script. I am also using jQuery 3.2.1 along with some other jQuery forks.
To hide my websites loading overlay, I use the following:
<script>
$(window).on("load", function(){
$('.loading-page').delay(3000).fadeOut(250);
});
</script>
You can write a function on a specific script file and call it in to your body element using onload attribute.
Exemple:
<script>
afterPageLoad() {
//your code here
}
</script>
Now call your script into your html page using script tag:
<script src="afterload.js"></script>
into your body element; add onload attribute like this:
<body onload="afterPageLoad();">
As Daniel says, you could use document.onload.
The various javascript frameworks hwoever (jQuery, Mootools, etc.) use a custom event 'domready', which I guess must be more effective. If you're developing with javascript, I'd highly recommend exploiting a framework, they massively increase your productivity.
Using the YUI library (I love it):
YAHOO.util.Event.onDOMReady(function(){
//your code
});
Portable and beautiful! However, if you don't use YUI for other stuff (see its doc) I would say that it's not worth to use it.
N.B. : to use this code you need to import 2 scripts
<script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/yahoo/yahoo-min.js" ></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.7.0/build/event/event-min.js" ></script>
i can catch page load by this code
<script>
console.log("logger saber");
window.onload = (event) => {
console.log('page is fully loaded');
document.getElementById("tafahomNameId_78ec7c44-beab-40de-9326-095f474519f4_$LookupField").value = 1;;
};
</script>
My advise use asnyc attribute for script tag thats help you to load the external scripts after page load
<script type="text/javascript" src="a.js" async></script>
<script type="text/javascript" src="b.js" async></script>
<script type="text/javascript">
$(window).bind("load", function() {
// your javascript event here
});
</script>
I'm using a javascript in my html page.. I have been recording the time taken using the navigation API .. When I try to findout the total load time (navigationStart - loadEventEnd) I find that the loadEventEnd is 0 . But also found that the loadEventStart value is recorded .. I print these values on console inside window.onload = function() {} . . From the above stats I assume that my function is called after the load event has fired and before it has completed .. However using onunload function gives me the result , the result cannot be viewed as it is printed in the console and unload event is triggered when moving away from the page .. Please help me find a solution .
Most likely you're getting a value of 0 because you're printing the information before the page has completed loading, try the following snippet:
window.onload = function(){
setTimeout(function(){
var t = performance.timing;
console.log(t.loadEventEnd - t.responseEnd);
}, 0);
}
That will make sure the numbers are printed after the page is actually ready. Got that snippet from here. Other information from that page you might find interesting:
Data from the API really comes to life when events are used in combination:
Network latency (): responseEnd-fetchStart.
The time taken for page load once the page is received from the server: loadEventEnd-responseEnd.
The whole process of navigation and page load: loadEventEnd-navigationStart.
Use the onload attribute in the tag as follows:-
<body onload="methodName();">
Try the following example for better understanding:-
<html>
<head>
<script type="text/javascript">
function test(){
alert("hello");
}
</script>
</head>
<body onload="test();">
<h5>Simple javascript test for page load</h5>
</body>
</html>
Try the following. i hope it will also work...
Use the window.onload object as follows:-
window.onload=function(){
//set of javascript statments...
}
or if you have any functions then use the window.onload as follows:-
window.onload=function_name
Have a look at the following example for better understanding of window.location
<html>
<head>
<script type="text/javascript">
window.onload = test;
function test(){
alert("hello");
}
</script>
</head>
<body>
<h5>Simple javascript test for page load</h5>
</body>
</html>
This question already has answers here:
Why does jQuery or a DOM method such as getElementById not find the element?
(6 answers)
Closed 8 years ago.
<html>
<head>
<title>Test javascript</title>
<script type="text/javascript">
var e = document.getElementById("db_info");
e.innerHTML='Found you';
</script>
</head>
<body>
<div id="content">
<div id="tables">
</div>
<div id="db_info">
</div>
</div>
</body>
</html>
If I use alert(e); it turns up null.... and obviously I don't get any "found you" on screen. What am I doing wrong?
The problem is that you are trying to access the element before it exists. You need to wait for the page to be fully loaded. A possible approach is to use the onload handler:
window.onload = function () {
var e = document.getElementById("db_info");
e.innerHTML='Found you';
};
Most common JavaScript libraries provide a DOM-ready event, though. This is better, since window.onload waits for all images, too. You do not need that in most cases.
Another approach is to place the script tag right before your closing </body>-tag, since everything in front of it is loaded at the time of execution, then.
How will the browser know when to run the code inside script tag? So, to make the code run after the window is loaded completely,
window.onload = doStuff;
function doStuff() {
var e = document.getElementById("db_info");
e.innerHTML='Found you';
}
The other alternative is to keep your <script...</script> just before the closing </body> tag.
Script is called before element exists.
You should try one of the following:
wrap code into a function and use a body onload event to call it.
put script at the end of document
use defer attribute into script tag declaration
The script is performed before the DOM of the body is built. Put it all into a function and call it from the onload of the body-element.
Run the code either in onload event, either just before you close body tag.
You try to find an element wich is not there at the moment you do it.
I've got the following code in a website:
window.onload = resize;
window.onresize = resize;
function resize(){
heightWithoutHeader = (window.innerHeight - 85) + "px";
document.getElementById("main-table").style.height = heightWithoutHeader;
document.getElementById("navigation").style.height = heightWithoutHeader;
}
The onresize works fine, but the onload event never fires. I've tried it in Firefox and Chrome and neither of them works.
Thank you for your help and go for the reputation! ;D
I think what's probably happening here is that your window.onload is being overridden later, check to make sure that it's not via things like <body onload="">
You can check this by alert(window.onload) in your re-size function, to see what's actually attached there.
I had this happen when I added 3rd party jQuery code we needed for a partner. I could have easily converted my antiquated window.onload to a jQuery document ready. That said, I wanted to know if there is a modern day, cross browser compatible solution.
There IS!
window.addEventListener ?
window.addEventListener("load",yourFunction,false) :
window.attachEvent && window.attachEvent("onload",yourFunction);
Now that I know ... I can convert my code to use the jQuery route. And, I will ask our partner to refactor their code so they stop affecting sites.
Source where I found the fix --> http://ckon.wordpress.com/2008/07/25/stop-using-windowonload-in-javascript/
Move the window.onload line to the end of the javascript file or after the initial function and it will work:
function resize(){
heightWithoutHeader = (window.innerHeight - 85) + "px";
document.getElementById("main-table").style.height = heightWithoutHeader;
document.getElementById("navigation").style.height = heightWithoutHeader;
}
// ...
// at the end of the file...
window.onload = resize;
window.onresize = resize;
But it's a best practice if you don't replace the onload too. Instead attach your function to the onload event:
function resize(){
heightWithoutHeader = (window.innerHeight - 85) + "px";
document.getElementById("main-table").style.height = heightWithoutHeader;
document.getElementById("navigation").style.height = heightWithoutHeader;
}
// ...
// at the end of the file...
window.addEventListener ?
window.addEventListener("load",resize,false)
:
window.attachEvent && window.attachEvent("onload",resize);
That worked for me and sorry for my english.
This answer is for those who came here because their window.onload does not trigger.
I have found that for the following to work
window.onload = myInitFunction;
or
window.addEventListener("load", myInitFunction);
the referred function (myInitFunction in this case) must reside (or be defined) within the same <script>-element or in a <script>-element that occurs before the <script>-element where the onload event is established. Otherwise it will not work.
So, this will not work:
<html>
<head>
<title>onload test</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script>
window.addEventListener("load", myInitFunction)
</script>
<script>
function myInitFunction() {
alert('myInitFunction');
}
</script>
</head>
<body>
onload test
</body>
</html>
But this will work:
<html>
<head>
<title>onload test</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script>
function myInitFunction() {
alert('myInitFunction');
}
</script>
<script>
window.addEventListener("load", myInitFunction)
</script>
</head>
<body>
onload test
</body>
</html>
And this will work (since we only have one <script>-element):
<html>
<head>
<title>onload test</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script>
window.addEventListener("load", myInitFunction)
function myInitFunction() {
alert('myInitFunction');
}
</script>
</head>
<body>
onload test
</body>
</html>
If you for some reason have two <script>-elements and cannot (or do not want to) merge them and you want the onload to be defined high up (i.e. in the first element), then you can solve it by
instead of writing
window.onload = myInitFunction;
you write
window.onload = function() { myInitFunction() };
or, instead of writing
window.addEventListener("load", myInitFunction);
you write
window.addEventListener("load", function() { myInitFunction() });
Another way to solve it is to use the old
<body onload="myInitFunction()">
For me, window.onload was not working when wrote inside script type="text/javascript tag.
Instead, needed to write the same in script language="Javascript" type="text/javascript tag and it worked fine.
In my case
window.addEventListener("load", function() {
myDropdownFunction();
});
surprisingly (for me) didn't help (I tried to set a value for dropdown when user uses browser backwards button). And window.onload didn't work for the reason Nick Craver♦ explained here above - it was overridden by <body onload="...">.
So I tried this using jQuery and it worked like a charm:
$(window).on('pageshow', function() {
alert("I'm happy");
});
This works for me, i think your problem is somewhere else:
function resize(){
var tester = document.getElementById("tester"),
html = tester.innerHTML
tester.innerHTML = html + "resize <br />"
}
window.onload = resize;
window.onresize = resize;
you can test it yourself here:
http://jsfiddle.net/Dzpeg/2/
are you sure its the only event called onLoad ? Maybe an other onLoad event creates a conflict
put "_blank" as the target param has solved in my case
let wind = open(url,"_blank","options here")
wind.onload = .... // works fine now
Just in case someone finds it useful, I was calling twice the function, instead of once:
window.onload = function() {...}
In my case the problem was that my script was being loaded dynamically by another one (e.g.: with $.getScript()) and when it ran the window 'load' event had already fired.
My solution:
if (
document.readyState === "complete" ||
document.readyState === "interactive"
) {
// load event already fired, this may happen if this script is loaded dynamically.
// Run immediately.
execOnLoad();
} else {
// SEE: https://stackoverflow.com/questions/2810825/javascript-event-window-onload-not-triggered
window.addEventListener
? window.addEventListener("load", execOnLoad, false)
: window.attachEvent && window.attachEvent("onload", execOnLoad);
}
This will be work when you call the "window.onload" next to the function resize()
If it's really in that order, it's definitely not going to work. You can't assign a function to an event handler before the function itself is declared.
This question already has answers here:
Why does jQuery or a DOM method such as getElementById not find the element?
(6 answers)
Closed 8 years ago.
I've been using document.GetElementById() successfully but from some time on I can't make it work again.
look at the following Code:
<html>
<head>
<title>no title</title>
<script type="text/javascript">
document.getElementById("ThisWillBeNull").innerHTML = "Why is this null?";
</script>
</head>
<body>
<div id="ThisWillBeNull"></div>
</body>
</html>
I am getting document.getElementById("parsedOutput") is null all the time now.
It doesn't matter if I use Firefox or Chrome, or which extensions I have enabled, or what headers I use for the HTML, it's always null and I can't find what could be wrong.
You can use the script tag like this:
<script defer>
// your JavaScript code goes here
</script>
The JavaScript will apply to all elements after everything is loaded.
Try this:
<script type="text/javascript">
window.onload = function() {
document.getElementById("ThisWillBeNull").innerHTML = "Why is this null?";
}
</script>
Without window.onload your script is never invoked. Javascript is an event based language so without an explicit event like onload, onclick, onmouseover, the scripts are not run.
<script type="text/javascript">
window.onload = function(){
document.getElementById("ThisWillBeNull").innerHTML = "Why is this null?";
}
</script>
Onload event:
The load event fires at the end of the document loading process. At this point, all of the objects in the document are in the DOM, and all the images and sub-frames have finished loading.
https://developer.mozilla.org/en/DOM/window.onload
Timing.
The document isn't ready, when you're getting the element.
You have to wait until the document is ready, before retrieving the element.
The browser is going to execute that script as soon as it finds it. At that point, the rest of the document hasn't loaded yet — there isn't any element with that id yet. If you run that code after that part of the document is loaded, it will work fine.
<script type="text/javascript">
window.onload += function() {
document.getElementById("ThisWillBeNull").innerHTML = "Why is this null?";
}
</script>
Use += to assign more eventHandlers to onload event of document.