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
});
Related
I got 2 questions. First of all, this is not my work. I'm currently looking at somebody else's JavaScript files. I can't give the exact code but I can show what I'm wondering.
In the JavaScript files I see a lot of $(document).ready(function(){});. I know what $(document).ready does, the callback function will be called when the DOM tree is loaded. Is there any reason why somebody would use more than one $(document).ready callback? I don't get the point.
Also, another thing I saw was a $(window).load inside a $(document).ready, like this:
$(document).ready(function() {
$(window).load(function() {
//...
});
});
From what I know, $(window).load() is called when everything of a page is loaded, like assets and images etc. I would think $(window).load() is the last thing called, after $(document).ready. Is there any time where $(window).load is called BEFORE $(document).ready and is there any reason why you would put a $(window).load inside a $(document).ready?
Yes, jQuery grants that ready event will be called before load. Even in IE8- (where DOMContentLoaded is not supported) it works in that way. But let's look at the following code:
<!doctype html>
<title>Ready vs load test</title>
<style>body {white-space: pre}</style>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script>
~function () {
function log(msg) {
document.body.innerHTML += msg + "\n";
}
function handler(msg) {
return function () {
log(msg);
}
}
$(window).load(handler("5. load #1"));
$(document).ready(handler("1. ready #2"));
$(window).load(handler("6. load #3"));
$(document).ready(handler("2. ready #4"));
$(document).ready(function () {
log("3. ready #5");
$(window).load(handler("8. load #6"));
});
$(document).ready(handler("4. ready #7"));
$(window).load(handler("7. load #8"));
}();
</script>
The result is
1. ready #2
2. ready #4
3. ready #5
4. ready #7
5. load #1
6. load #3
7. load #8
8. load #6
Look at lines 7 and 8. The load handled attached from ready event is the last one. So by using this way we can ensure that all previously added (during scripts parsing and exection) load handlers have already been called.
so using $(window).load outside the $(document).ready and inside doesn't change that much from how it'd affect how stuff work?
Actually it can affect script execution. The first version works and the second doesn't:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
$(document).ready(function () {
$(window).load(function () {
$.magic.value = 12;
});
});
</script>
<script>
$(window).load(function () {
$.magic = {};
});
</script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
$(document).ready(function () {
});
$(window).load(function () {
$.magic.value = 12;
});
</script>
<script>
$(window).load(function () {
$.magic = {};
});
</script>
$(document).ready kicks in when all nodes of the DOM have been loaded but not necessarily their content, that's what's $(window).load is for, e.g. an img-ele can be present, yet it's content – the image – hasn't been loaded.
So, you're right, use each listener only once and don't nest them.
In my webpage I have script like this :
<head>
<script src="scripts/effect.js"></script>
<script>
if (document.readyState == 'complete') {
doOnLoad();
}
$(window).bind("load", doOnLoad);
function doOnLoad() {
console.log("here..");
}
</script>
</head>
effect.js file contains script as shown below:
$( document ).ready(function(){
console.log("yes");
// here I've script for reading a text file using ajax and manipulating the result from text file
$.ajax({
// code goes here
console.log("ajax");
});
});
The problem is that when I run the page initially, I'm not getting the result. At that time I get console output as
yes
here..
ajax
But when I refresh the page again I am getting the result and console prints like :
yes
ajax
here..
How can I run window.load after the document.ready is completed.
Can anyone help me to fix this? Thanks in advance.
This is all about the timing of script execution. It sounds like the behaviour is changing once certain resources have been loaded and cached.
The first piece of code you have is a bit confusing:
if (document.readyState == 'complete') {
doOnLoad();
}
I'm not sure why you need this as well as the on load handler? It looks like that condition is never going to equal true anyway, as that code will run immediately before the document has finished loading. At the very least, I would put a console.log in this block, so I could determine what's triggering doOnLoad.
Try replacing the script on your page for just the following:
$(window).on("load", doOnLoad);
function doOnLoad() {
console.log("here..");
}
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
I've seen a few questions like the one I'll ask but nothing identical. I have two html files, main and today. What I want to do is load today.html via AJAX into a child div in main.html. Sometime after load, I would like to call a function that resides in main.html from today.html
Within Main I have this function:
function drawCircle (size){
alert('DRAWING');
}
This AJAX load:
$("#leftofad").ajax({
url: ":Today.html?r="+genRand(),
type: 'GET',
success: function(data) { },
error: function() { alert('Failed!'); },
});
And this div:
<div id="leftofad"></div>
In Today.html I have
<script type="text/javascript">
$(document).ready(function(){
drawCircle (100);
});
</script>
The load is going well but Today.html doesnt seem to recognize the drawCircle function. I've tried several precursors including this., window., and parent..
I understand that I can use the callback method of the AJAX loader in jQuery but I don't necessarily want to call drawCircle when the load is complete. I may want to wait a bit or do it as a result of an action from the user. Is it possible to reference these functions from an AJAX-loaded div? If not, can I use an alternative method like events and listeners to fire the drawCircle function?
Since you will be loading JS into your page, try calling the function directly?
(The ready function won't run as the main page is already loaded)
Main.html
<script type="text/javascript">
function drawCircle(size) { alert("DRAWING" + size); }
$(function() {
$("#leftofad").load("Today.html?r="+genRand(), function() {
alert('loaded successfully!');
});
});
</script>
<div id="leftofad"></div>
Today.html
<script type="text/javascript">
drawCircle(100);
</script>
If this doesn't work, I strongly suspect that JavaScript returned in an AJAX call is not executed.
In this case, refer to: How to execute javascript inside a script tag returned by an ajax response
$("#leftofad").ajax is not proper.
jQuery's $.ajax function does not use a selector.
What you can use is load:
$("#leftofad").load("Today.html?r="+genRand(), function(){
alert('loaded successfully!');
});
Everyone here has some good answers, but I believe there is a knowledge gap and we are missing some information. If I were you, I would add an alert to the script in the Today.html file right before the drawCirle. Then I would run this page using IE or Chrome dev tools or Firebug in Firefox. When the alert is displayed you can put a breakpoint in the javascript code. Then check your global scope to try and locate drawCirle...
Sorry this is not an exact answer, but with javascript files you need to use debugging tools for this.
while there isn't really a document.ready function for a div, there is a hack that works just as if so:
create your returning data as a full html page:
<html>
<head>
<script type='text/javascript'>
$(document).ready( function () {
do-this;
to-that;
....
});
</script>
</head>
<body>
<%
your possible vbscript
%>
the rest of stuff to be loaded into that div
</body>
</html>
Then, you can have as many cascading div loading from different page loading and .... rinse and repeat ... forever .... EXPERIMENT with different DOCTYPE to see the different results.
EDIT:
Then, of course, you load the original MAIN with
$('#thedivid').load('url-of-the-html-returning-page');
Which, in turn, can have the VERY SAME call in the returning page document.ready as, for example; $('#thedivid-inthereturningdata-html-page').load('url-of-the-html-of-the-child-process-for-whaterver); .... and so on.
Go ahead, PLAY AROUND and make wonderful ajax based applications ....
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.