I have a jquery script which I need to run only once everything else on the page, including some other javascripts (over which I have no control) have finished doing their thing.
I though perhaps there was an alternative to $(document).ready but I haven't been able to find it.
You can have $(document).ready() multiple times in a page. The code gets run in the sequence in which it appears.
You can use the $(window).load() event for your code since this happens after the page is fully loaded and all the code in the various $(document).ready() handlers have finished running.
$(window).load(function(){
//your code here
});
This code block solve my problem,
<script type="text/javascript">
$(window).bind("load", function () {
// Code here
});
</script>
Multiple $(document).ready() will fire in order top down on the page. The last $(document).ready() will fire last on the page. Inside the last $(document).ready(), you can trigger a new custom event to fire after all the others..
Wrap your code in an event handler for the new custom event.
<html>
<head>
<script>
$(document).on("my-event-afterLastDocumentReady", function () {
// Fires LAST
});
$(document).ready(function() {
// Fires FIRST
});
$(document).ready(function() {
// Fires SECOND
});
$(document).ready(function() {
// Fires THIRD
});
</script>
<body>
... other code, scripts, etc....
</body>
</html>
<script>
$(document).ready(function() {
// Fires FOURTH
// This event will fire after all the other $(document).ready() functions have completed.
// Usefull when your script is at the top of the page, but you need it run last
$(document).trigger("my-event-afterLastDocumentReady");
});
</script>
From here:
// Add jQuery
var GM_JQ = document.createElement('script');
GM_JQ.src = 'http://jquery.com/src/jquery-latest.js';
GM_JQ.type = 'text/javascript';
document.getElementsByTagName('head')[0].appendChild(GM_JQ);
// Check if jQuery's loaded
function GM_wait()
{
if(typeof unsafeWindow.jQuery == 'undefined')
{
window.setTimeout(GM_wait,100);
}
else
{
$ = unsafeWindow.jQuery;
letsJQuery();
}
}
GM_wait();
// All your GM code must be inside this function
function letsJQuery()
{
// Do your jQuery stuff in here
}
This will wait until jQuery is loaded to use it, but you can use the same concept, setting variables in your other scripts (or checking them if they're not your script) to wait until they're loaded to use them.
For example, on my site, I use this for asynchronous JS loading and waiting until they're finished before doing anything with them using jQuery:
<script type="text/javascript" language="JavaScript">
function js(url){
s = document.createElement("script");
s.type = "text/javascript";
s.src = url;
document.getElementsByTagName("head")[0].appendChild(s);
}
js("/js/jquery-ui.js");
js("/js/jrails.js");
js("/js/jquery.jgrowl-min.js");
js("/js/jquery.scrollTo-min.js");
js("/js/jquery.corner-min.js");
js("/js/jquery.cookie-min.js");
js("/js/application-min.js");
function JS_wait() {
if (typeof $.cookie == 'undefined' || // set in jquery.cookie-min.js
typeof getLastViewedAnchor == 'undefined' || // set in application-min.js
typeof getLastViewedArchive == 'undefined' || // set in application-min.js
typeof getAntiSpamValue == 'undefined') // set in application-min.js
{
window.setTimeout(JS_wait, 100);
}
else
{
JS_ready();
}
}
function JS_ready() {
// snipped
};
$(document).ready(JS_wait);
</script>
Have you tried loading all the initialization functions using the $().ready, running the jQuery function you wanted last?
Perhaps you can use setTimeout() on the $().ready function you wanted to run, calling the functionality you wanted to load.
Or, use setInterval() and have the interval check to see if all the other load functions have completed (store the status in a boolean variable). When conditions are met, you could cancel the interval and run the load function.
It turns out that because of a peculiar mixture of javascript frameworks that I needed to initiate the script using an event listener provide by one of the other frameworks.
The following script ensures that my_finalFunction runs after your page has been fully loaded with images, stylesheets and external content:
<script>
document.addEventListener("load", my_finalFunction, false);
function my_finalFunction(e) {
/* things to do after all has been loaded */
}
</script>
A good explanation is provided by kirupa on running your code at the right time, see https://www.kirupa.com/html5/running_your_code_at_the_right_time.htm.
Related
I need to execute some JavaScript code when the page has fully loaded. This includes things like images.
I know you can check if the DOM is ready, but I don’t know if this is the same as when the page is fully loaded.
That's called load. It came waaaaay before DOM ready was around, and DOM ready was actually created for the exact reason that load waited on images.
window.addEventListener('load', function () {
alert("It's loaded!")
})
For completeness sake, you might also want to bind it to DOMContentLoaded, which is now widely supported
document.addEventListener("DOMContentLoaded", function(event){
// your code here
});
More info: https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded
Usually you can use window.onload, but you may notice that recent browsers don't fire window.onload when you use the back/forward history buttons.
Some people suggest weird contortions to work around this problem, but really if you just make a window.onunload handler (even one that doesn't do anything), this caching behavior will be disabled in all browsers. The MDN documents this "feature" pretty well, but for some reason there are still people using setInterval and other weird hacks.
Some versions of Opera have a bug that can be worked around by adding the following somewhere in your page:
<script>history.navigationMode = 'compatible';</script>
If you're just trying to get a javascript function called once per-view (and not necessarily after the DOM is finished loading), you can do something like this:
<img src="javascript:location.href='javascript:yourFunction();';">
For example, I use this trick to preload a very large file into the cache on a loading screen:
<img src="bigfile"
onload="this.location.href='javascript:location.href=\'javascript:doredir();\';';doredir();">
Try this it Only Run After Entire Page Has Loaded
By Javascript
window.onload = function(){
// code goes here
};
By Jquery
$(window).bind("load", function() {
// code goes here
});
Try this code
document.onreadystatechange = function () {
if (document.readyState == "complete") {
initApplication();
}
}
visit https://developer.mozilla.org/en-US/docs/DOM/document.readyState for more details
Javascript using the onLoad() event, will wait for the page to be loaded before executing.
<body onload="somecode();" >
If you're using the jQuery framework's document ready function the code will load as soon as the DOM is loaded and before the page contents are loaded:
$(document).ready(function() {
// jQuery code goes here
});
the window.onload event will fire when everything is loaded, including images etc.
You would want to check the DOM ready status if you wanted your js code to execute as early as possible, but you still need to access DOM elements.
You may want to use window.onload, as the docs indicate that it's not fired until both the DOM is ready and ALL of the other assets in the page (images, etc.) are loaded.
In modern browsers with modern javascript (>= 2015) you can add type="module" to your script tag, and everything inside that script will execute after whole page loads. e.g:
<script type="module">
alert("runs after") // Whole page loads before this line execute
</script>
<script>
alert("runs before")
</script>
also older browsers will understand nomodule attribute. Something like this:
<script nomodule>
alert("tuns after")
</script>
For more information you can visit javascript.info.
And here's a way to do it with PrototypeJS:
Event.observe(window, 'load', function(event) {
// Do stuff
});
The onload property of the GlobalEventHandlers mixin is an event
handler for the load event of a Window, XMLHttpRequest, element,
etc., which fires when the resource has loaded.
So basically javascript already has onload method on window which get executed which page fully loaded including images...
You can do something:
var spinner = true;
window.onload = function() {
//whatever you like to do now, for example hide the spinner in this case
spinner = false;
};
Completing the answers from #Matchu and #abSiddique.
This:
window.addEventListener('load', (event) => {
console.log('page is fully loaded');
});
Is the same as this but using the onload event handler property:
window.onload = (event) => {
console.log('page is fully loaded');
};
Source:
https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event
Live example here:
https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event#live_example
If you need to use many onload use $(window).load instead (jQuery):
$(window).load(function() {
//code
});
2019 update: This is was the answer that worked for me. As I needed multiple ajax requests to fire and return data first to count the list items.
$(document).ajaxComplete(function(){
alert("Everything is ready now!");
});
I use CookieBot in our html pages. CookieBot javascript doesn't load in test environment and throws a net::ERR_ABORTED 404 error.
When this happens, the loading spinner in the page keeps displaying after the page loading has been completed.
I tried following options to invoke a listener after page loading is completed. But none of them works:
document.addEventListener("load", (e) => {
console.log("document load");
});
document.addEventListener("DOMContentLoaded", function(event) {
console.log("DOMContentLoaded");
});
$(document).ready(function() {
console.log("ready!");
});
$(document).ready(function() {
console.log("document is ready");
});
$(window).on("load", function(){
console.log("window load!");
});
window.onload = function () {
console.log("window onload!");
};
I guess CookieBot script overrides my listeners. Here is an example where listener is not invoked. When you remove the CookieBot script it runs: https://jsfiddle.net/hkarakose/4by26Lr3/1/
How can I invoke a function after page loading is finished?
You can invoke a function after page loading with:
window.onload = function() {
//here you can write your function and invoke it.
}
Edit:
Maybe I didn't understand your request, but now I'm reading more carefully.
The problem is in the script, right? If you insert the script on HEAD, it will be loaded first.
You could insert the type of the script in this way:
type = "text / plain" with a data-attribute: data-attribute = "script-cookie".
Then change the type once everything has been loaded, like this:
window.onload = function () {
var allPrefScript = document.querySelectorAll ("script [data-attribute =" script-cookie "]");
allPrefScript [0] .setAttribute ("type", "text / javascript");
}
Although #davilink92's answer works, I solved this issue in a more practical way.
I attached external script loading to window load event:
window.addEventListener('load', function () {
$.getScript("https://consent.cookiebot.com/uc.js?cbid=d180eb7a-8f13-4549-bacc-6d4a6dfb5da8&culture=en");
$("#global-loader").fadeOut("slow");
});
In this way, the script couldn't prevent the window load event listener to be invoked by the browser. And thus, I was able to remove the loading spinner after page is loaded.
I have the habit to use document.addEventListener("load", (e) => {console.log("loaded"); })
Can you show us more code to see if your problem is here? I think all of yours tests are correct and I dont understand why it isnt working.
How can i define more than one onload function (but different!)
in the same js file,
for ex,
file.js:
//---on load forpage1
$( document ).ready( handler ){
do something one
}
//---on load for page2
$( document ).ready( handler ){
do something else
}
and import it in both of the 2 pages:
for ex:
page1:
<!DOCTYPE>
<html>
<head>
<script type="text/javascript" src="file.js"></script>
</head>
page2:
<!DOCTYPE>
<html>
<head>
<script type="text/javascript" src="file.js"></script>
</head>
I'm assuming you ask this because you want to execute different code on the other page.
You could for example check location.href to see which page is currently being called.
More usual though is to use server side scripting to determine the current page and refer to the javascript accordingly.
Edit for an example:
$(function () {
var page = window.location.pathname;
if (page == "/index.html") {
// code here
}
else if (page == "/contact.html") {
// other code here
}
});
It depends what you're trying to achieve. If you want several functions to run when your page loads, the code in your post is almost correct:
$(document).ready(function() {
console.log("Function 1 running");
});
$(document).ready(function() {
console.log("Function 2 running");
}
You can also pre-define these functions if you want, and pass them to your $(document).ready() call:
function handler_1() {
console.log("Handler_1 is running");
}
function handler_2() {
console.log("Handler_2 is running");
}
$(document).ready(handler_1);
$(document).ready(handler_2);
And you can even use the jQuery shortcut $():
$(handler_1);
$(handler_2);
But if you want only one function to run when the page loads - depending on which page loaded - you'll need to take another approach. You could define all your code in script.js, and load init_page1.js from page 1, init_page2.js from page 2, etc. Those init files would call whichever setup function is appropriate for the page.
Alternatively, you could add a data attribute on your body tag indicating what page it's on, and have your $(document).ready() call the correct handler. Something like this:
$(document).ready(function() {
var page_type = $('body').data('page-type');
if (page_type == 'home') {
handler_1();
} else if (page_type == 'profile') {
handler_2();
}
});
And then, in your HTML file:
<body data-page-type="profile">
Possibly the neatest solution, though, is to have the callback functions determine whether they're relevant to the page. That way you can re-use them wherever you like. So your script would look something more like this:
function handler_1() { // Only for home page
if ($('body').data('page-type') != 'home') {
return;
}
console.log("I'm the handler_1 function");
}
function handler_2() { // Only for profile page
if ($('body').data('page-type') != 'profile') {
return;
}
}
$(handler_1);
$(handler_2);
Really, though, if you can avoid coding this into your JavaScript, you should. It's better to only include scripts that you know are required for that particular page to function.
In addition to $( document ).ready, which is called after the DOM is fully loaded for the current HTML file, including all images, the $(window).load is another method to detect DOM readiness that is not fired until all sub-elements, like iframes have been loaded and are available for use.
As to your original question, you can define as many $( document ).ready functions as you like; they are executed in the order they are found.
You can have multiple blocks of $(document).ready – but it won't solve your problem as they'll all be called once the DOM is loaded.
I'd recommend you to take a look at Paul Irish's DOM-based Routing.
Your question was very vague but I'm assuming you want multiple items to be called upon the page being loaded, in which the first example is.
document.ready(function(handler){
/*Do thing one*/
/*Do thing two*/
});
But if you mean for them to be called with different scenarios then you would use the handler passed in to check the status of the document and call a different item.
document.ready(function(handler){
if(handler==bar)
//Do thing one
else if(handler==foo)
//Do thing two
else
//Do thing three
});
Trying to make a simple widget.
Steps:
1) Load jQuery if not already there
2) Callback a function
<html>
<head>
<script type="text/javascript">
function load(callback){
console.log('load');
if (typeof jQuery !== "function") {
var js = document.createElement("script");
var he = document.getElementsByTagName('head')[0];
js.type = "text/javascript";
js.src = "http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js";
he.appendChild(js);
js.addEventListener("load", function () {
callback();
});
}
else
{
callback();
}
}
load(function(){
chart();
})
function chart(){
$('#chart').html("id : "+Math.random());
}
// alert('This alert breaks!');
</script>
</head>
<body>
<div id="chart"></div>
</body>
</html>
Code works without alert. Cant understand the context issue
Thanks
Alright, figured out the problem.
Your code is not inside a DOM ready handler.
It will work if the alert isnt there since the function call is asynchronous and the DOM is ready before the AJAX is complete.
but when the alert is there, it create a breakpoint in your code and the DOM will not complete until you click ok. The probleme is that the AJAX request isnt stopped. When you click ok, the AJAX will be finish and run the callback before the DOM is ready.
Move your script block out of the head tag and place it at the end of the body right before </body>.
I'm using a mix of .ready() and .load() to execute my desired function.
jQuery(document).ready(function($) {
$("img").load(function() {
// Function goes here
});
});
As you can see, this waits for the DOM to be ready, then on each <img> load, it executes the code.
If I only had one image to load this would be simple.
But the problem is -- what if I have 10 images to be loaded? The function will be called 10 times due to each image loading one by one, and that's not a very efficient way to go about it just to achieve what I want.
So here's the question -- is there a more efficient way to wait for all images to load, then execute the function once?
You could do something like this to avoid having your function run multiple times.
jQuery(document).ready(function($) {
var nrOfImages = $("img").length;
$("img").load(function() {
if(--nrOfImages == 0)
{
// Function goes here
}
});
});
jQuery(window).load(function() {
alert("page finished loading now.");
});
jQuery(window).load(...) will be triggered after all content on the page has been loaded. This different from jQuery(document).load(...) which is triggered after the DOM has been loaded. I think this will solve your issue.
If anybody wants to know, my final result was this:
(function($) {
$(window).load(function(){
// Function goes here
});
})(jQuery);
that's because
jQuery(window).load(function($) {});
isn't a jQuery object, as referenced in this question:
Calling jQuery on (window).load and passing variable for 'No Conflict' code