In what order will these functions get executed? - javascript

I am rewriting a project of mine and this time I decided to use self invoking functions to save a bit of code, but I became very uncertain if this would even work since I don't want the self invoking functions to be run before page has loaded + the init function has been run.
The expected execution order I want is this:
init: function() {
//some code gets executed here
createCalendar(2015);
}
addEventListnrs: (function() {
//event listeners gets added here on elements that gets created
//in the createCalendar function
})()
createCalendar: function(year) {
//creates elements that the addEventListnrs uses
}
window.onload = init;
Question is, is this what I'm going to get or will the addEventListnrs function invoke itself before init gets run?

Assuming your labels are valid code (i.e. you've left some code out)
The IIFE labelled addEventListnrs invokes itself as soon as the interpreter reaches it
...some time passes as the page loads... ...and it finishes loading
The load event is sent to window
init is invoked by the listener
createCalendar is invoked by init

Related

Is there a way to call function defined inside onload from an external file

Following is a sample code created based on the scenario. showData() function is defined inside a javascript load function. I wanted to call showData() from another file maybe on a button click. I know this will work if the showData is made global. It's not possible to make the function global, as in this scenario it's a dynamically generated code. Is there anyway in JS that allows to call such functions ?
// Not possible to change the structure of this file as its coming dynamically
window.addEventListener("load", function() {
showData(); // 1st time call
function showData() {
console.log('starting execution')
}
});
// Calling from another file
showData(); // 2nd time call - not possible
No.
The function is declared inside another function. Its scope is that function.
Unless you change that code to make it a global, it isn't accessible from outside the containing function at all.
If the structure of the code can't be changed, perhaps you could try attaching your function to the global window object, like:
window.addEventListener("load", function() {
// attached to window
window.showData = function() {
console.log('starting execution')
};
window.showData(); // 1st time call
});
// Calling from another file
window.showData();
But make sure the second call (from the other file) has a little bit of a delay (remember the eventListener has to be attached to the window first, before the function becomes available).
You could try:
// second call
setTimeout(function() {
window.showData();
}, 1000);

difference between the window.onload and (function() {})();

I'm actually seeing this script in javascript (function() { //some code; })(); than using the window.onload what is the difference of the two? and which of the two is prefer to use?
An Immediately Invoked Function Expression is invoked immediately.
A function assigned to onload is invoked when the load event fires (which is when the page and its dependencies have finished loading).
The window.onload() waits for the window/page to be loaded before running it.
(function() {})(); run instantly if inserted into head section, before the DOM is constructed.

Why variable appears undefined outside document ready tags

I have observed a strange behavior while learning jQuery and Javascript. When I call a variable that is defined inside the $(document).ready, from outside these tags it appears undefined, even when I define it as a global variable,
For example:
$(document).ready(function() {
myVar = "test";
});
alert(typeof(myVar));
//Results "undefined"
If I call the same variable inside the document.ready tags it works as expected
$(document).ready(function() {
myVar = "test";
alert(typeof(myVar));
//Results "String"
});
The result is same even after using window prefix.
$(document).ready(function() {
window.myVar = "test";
});
alert(typeof(window.myVar));
//Results "undefined"
I understand about the variable scopes but why even global variables aren't working this way. I am so confused.
The code inside the "ready" handler will not run until the DOM has been fully built. The code outside the handler will run as soon as it is encountered. Thus, your alert() runs before the code in the handler runs, so the outcome makes perfect sense: the global variable has not yet been initialized, so its value is undefined.
You can see the sequence of execution clearly by putting alert() (or, better, console.log()) calls inside the "ready" handler:
$(document).ready(function() {
console.log("In the 'ready' handler");
});
console.log("Outside the 'ready' handler");
When that runs, you'll see the "Outside" message logged first.
Because the alert() is executed before your document is perfectly ready.. You may try even by declaring the variable before $(document).ready() still it will return undefined..
The $(document).ready() gets fired after the page is fully loaded
When the script tag is fully loaded the alert gets executed.
So
Script tag is loaded => Execute alert
Continue loading page
Page completly loaded => fire $(document).ready
You var is getting set
The alert gets executed before your var is set
The other answers are correct but it is probably important to also note the $(document).ready(...) is also hiding your variable from the global scope. You could declare your variable then update it within the function
var myVar;
$(document).ready(function() {
myVar = "test";
});
console.log(myVar) // test
The execution plan it's like
//this statement shall fix the driver, not run it
$(document).ready(function() {//-->this it's an event handler waiting to be fired when content is fully loaded
myVar = "test";//-->myVar won't exists until this event is triggered
});
//this execute the alert function but myVar not exist yet
alert(typeof(myVar));
$(document).ready() is like to assign an event who will execute after the content is loaded, which means alert(myVar) will run before the lambda execution which was set as the content-loaded event. I hope you'll understand me.

How to set JS events at the right time

In the rails.js that came with my rails (3.0.x, still with prototype), I see the following structure:
(function() {
// ...
document.on("click", ...
})();
What exactly is accomplished with the wrapping of the whole code in the anonymous function? Is this a valid way to delay the code until the dom has loaded or only the document object?
In my project, I currently have a lot of setup code inside a Event.observe(document, 'dom:loaded', function() { ... } block. I was wondering, if I should adopt the pattern above when I refactor my code.
You have stumbled across the module pattern. It is useful because variables inside the immediately invoked function are local and don't pollute the global namespace.
(function(){
var something = 17;
//can use something inside here
}());
//but not here anymore
Not ethat there is no difference in timeing since the function is immediately invoked (in the final () bit)
The self-invoking anonymous function will trigger what is inside immediately, which has nothing to do with delaying the code.
To make the code block inside be executed after the DOM is ready, you have to have DOMready listener. I guess the code you mentioned Event.observe(document, 'dom:loaded', function() { ... } is the one.

How can I call a function at the very end of document.ready

I have multiple document.ready functions on a page and I want a function to be called when all my document.ready functions have been executed. I simply want the function to be called
at the very end, after all other document.ready functions have executed.
An example of this could be that each document.ready function increments a global variable when it has been executed, and the last function needs to check the value of that variable at the very end.
Any ideas ?
This will be enough:
$(function () {
window.setTimeout(function () {
// your stuff here
}, 0);
});
This postpones the execution of your function after all other in the document ready queue are executed.
First idea (for small apps): Tidy up
You can just put everything in one $().ready() call. It might nieed refactoring, but it's the right thing to do in most cases.
Second idea: A Mediator [pattern]
Create a mediator class that will register functions and call its register() instead of $().ready(). When all functions are registered You just loop over the collection and run them in the single and only $().ready() and You have a point in code that is just after all is executed.
I am currently developing a kind of a framework for jquery applications that has a mediator. I might stick together a small version including the mediator if You're interested.
Why not just calling it after all the others ?
$(function(){
func1();
...
funcN();
functionThatNeedsToBeCalledAfter();
});
Of course you will have to cleanup your code to have only 1 place where the document ready function is used... but then your code would be more readable so it's worth it.
little hacky but might work, create a variable inside jquery scope like that
$.imDone = false
then create a function with setTimeout called after short time to lookup for the variable ser to true
var theLastFunctionToCall = function(){
alert('I m the last being called!')
}
var trigger = function(){
$.imDone?theLastFunctionToCall():window.setTimeout(trigger,10);
}
trigger();
I only recommend this when u have different $(document).ready in different big js files, but if you can refactor i sincerelly recommend an optimal solution.

Categories