How to set JS events at the right time - javascript

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.

Related

Unattached anonymous functions and doubly named methods in javascript?

I'm debugging an app that uses .NET's scriptmanager.
It may be a glitch in firebug, but when I read through the code there are a lot of lines like the following:
// anonymous functions not attached as handlers and not called immediately
function () {
//code
}
// named functions added as methods
myObj = {
myMethod: function myFunctionName() {
//code
}
}
Are these lines valid and, if so, what do they do and what possible reason would there be for coding like this (and I won't accept "It's microsoft - what d'you expect" as an answer)?
This might be worth a read: How does an anonymous function in JavaScript work?
They are there because some busy programmer was intending to do something and ran out of time, but left the stub as a reminder of work to be done. They do nothing as of yet.
or to watermark the code for checks that are done elsewhere in the logic
or simply put there to obfuscate...

jQuery document.ready vs self calling anonymous function

What is the difference between these two.
$(document).ready(function(){ ... });
(function(){ ... })();
Are these both functions called at the same time?
I know, document.ready will be triggered when the entire HTML page is rendered by the browser but what about 2nd function (self calling anonymous function). Does it wait for browser to complete rendering the page or it is called whenever it is encountered?
$(document).ready(function(){ ... }); or short $(function(){...});
This Function is called when the DOM is ready which means, you can start to query elements for instance. .ready() will use different ways on different browsers to make sure that the DOM really IS ready.
(function(){ ... })();
That is nothing else than a function that invokes itself as soon as possible when the browser is interpreting your ecma-/javascript. Therefor, its very unlikely that you can successfully act on DOM elements here.
(function(){...})(); will be executed as soon as it is encountered in the Javascript.
$(document).ready() will be executed once the document is loaded. $(function(){...}); is a shortcut for $(document).ready() and does the exact same thing.
The following code will be executed when the DOM (Document object model) is ready for JavaScript code to execute.
$(document).ready(function(){
// Write code here
});
The short hand for the above code is:
$(function(){
// write code here
});
The code shown below is a self-invoking anonymous JavaScript function, and will be executed as soon as
browser interprets it:
(function(){
//write code here
})(); // It is the parenthesis here that call the function.
The jQuery self-invoking function shown below, passes the global jQuery object as an argument
to function($). This enables $ to be used locally within the self-invoking function without needing
to traverse the global scope for a definition. jQuery is not the only library that makes use of $, so this
reduces potential naming conflicts.
(function($){
//some code
})(jQuery);
$(document).ready(function() { ... }); simply binds that function to the ready event of the document, so, as you said, when the document loads, the event triggers.
(function($) { ... })(jQuery); is actually a construct of Javascript, and all that piece of code does is pass the jQuery object into function($) as a parameter and runs the function, so inside that function, $ always refers to the jQuery object. This can help resolve namespacing conflicts, etc.
So #1 is executed when the document is loaded, while #2 is run immediately, with the jQuery object named $ as shorthand.
document.ready run after DOM is "constructed". Self-invoking functions runs instantly - if inserted into <head>, before DOM is constructed.

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.

simple javascript question

I have a 2000 line jquery file, I just broke up the file into smaller ones, If I have a function in the first file, that file # 2 is referring to, it's coming up undefined.
Every file is is wrapped in a jquery ready function, What's the best way to do this?
If the function in question is declared within the scope of the ready handler, it won't be accessible to any other code, including other ready handlers.
What you need to do is define the function in the global scope:
function foo()
{
alert('foo');
}
$(document).ready(function()
{
foo();
});
P.S. A more concise way of adding a ready handler is this:
$(function()
{
foo();
});
Edit: If the contents of each of your divided ready handlers rely on the previous sections, then you can't split them up, for the reasons outlines above. What would be more sensible would be to factor out the bulk of the logic into independent functions, put these in their own files outside the ready event handler, and then call them from within the handler.
Edit: To further clarify, consider this handler:
$(function()
{
var foo = 'foo';
var bar = 'bar';
alert(foo);
alert(bar);
});
I might then split this up:
$(function()
{
var foo = 'foo';
var bar = 'bar';
});
$(function()
{
alert(foo);
alert(bar);
});
The problem with this is that foo and bar are defined in the first handler, and when they are used in the second handler, they have gone out of scope.
Any continuous flow of logic like this needs to be in the same scope (in this case, the event handler).
Function definition should not be wrapped in another function. Not unless you really want that function definition to be private. And if I understand correctly that's not your intention.
Only wrap function invocation in the jQuery ready function.
If you're worried about your functions clashing with third party function names then namespace them:
var myFunctions = {}
myFunctions.doThis = function () {}
myFunctions.doThat = function () {}
But really, you only need to worry about this if you're creating a mashup or library for others to use. On your own site YOU have control of what gets included in javascript.
Actually, for performance reasons, it may be better to keep it in one file; multiple requests actually can take up more bandwidth... but as separate files, you would need to order them in a particular order so that there is a logical sequence. Instead of having everything in a document.ready, have each script define a method, that the page will execute within its own document.ready handler, so that you can maintain that order.
Most likely the reason it's coming up undefined is because when you have separate ready calls, the scope of the code inside those calls is different.
I would reorganize my code. Any shared functions can be attached to the jQuery object directly, using $.extend. This is what we do for our application and it works well.
See this question. Hope it helps.
Everyfile shouldnt have a ready function. Only one file should have the ready function and that should be the last file.
"wrapped in a jquery ready function" is nothing else than binding stuff to the ready event that is fired when jQuery thinks the DOM is ready.
You should only bind methods that is depending on the DOM to the ready event. It doesnt matter how many binds you make, all of the methods will be executed in the binding order in the end.
Functions provide scope in JavaScript. Your code in the jquery.ready is an anonymous function, so it is unaware of the other scopes. remove the wrappings for those JavaScript functions and declare them as regular functions, a la
$(document).ready(function ()
{
functionFromFile1();
functionFromFile2();
};

How should I initialize jQuery?

I have seen this (I'm also using it):
$(document).ready(function(){
// do jQuery
})
and also this (I have tried lately):
(function(){
// do jQuery
})(jQuery)
both work fine.
What is the difference of the two (except on how it looks)?
Which one is more proper to use?
The second example you show is a self executing anonymous function. Every separate JS file you use would probably benefit from using it. It provides a private scope where everything you declare with the var keyword remains inside that scope only:
(function($){
var special = "nice!";
})(jQuery);
alert(special); // would be undefined
The first example is shorthand for $(document).ready which fires when the DOM can be manipulated.
A couple cool things about it. First, you can use it inside the self executing function:
(function($){
$(function(){
// Run on DOM ready
});
// Run right away
})(jQuery);
Secondly, if all you need is a few lines in document ready, you can combine both the private scope and the DOM ready function like this:
jQuery(function($){
// $ = jQuery regardless of what it means
// outside this DOM ready function
});
The first example runs the function when the DOM tree is built.
The second example runs the function right away.
If you look closely, in the second example, there are two parentheses after the function declaration ( in this particular case, you pass in the global jQuery object as an argument to avoid conflict ), thereby immediately invoking the function
The right function to use depends on when you want the function to run.
If you want to run a function on DOMReady ( the ready event ), you can use $( document ).ready like you mentioned or the shorthand $( function() {...} ).
Otherwise, if you want to run a function immediately and have anonymous function scope, use the second example.
In addition to all the previous answers,
jQuery have three initialization methods that can be used:
The traditional method compatible with most browsers, see code:
$(document).ready(function () {
});
The short-hand method, see code:
$(function () {
});
The implicit method, see code:
$().ready(function () {
});
They all work for modern browsers and safe to use.
I always use the first. The second appears to be a way to protect against jquery being overriden. One reason you might do this is if you don't know what other scripts will be loaded on the page. If all of your stuff depends on, say, jquery 1.3, and you're in an environment where you don't control the entire page, your code could break if someone loads in jquery 1.4. Sounds ugly, but this sort of thing does happen. So you can cover your butt by creating a closure immediately after you load jquery, and holding your version of jquery inside that closure. I think that's what's going on in the second example.
Neither one actually initializes jquery. Jquery takes care of any initilazation it needs on its own. You'd still, quite likely wind up using the first example even if you were using the second, you'd just be putting the $(document).ready inside the function in your second example.
Though it's an old conversation, I want to share my way to init jQuery
;(function($, window, document) {
// Your Code Goes Here
}(window.jQuery, window, document));
By this, you can sure about that nothing can go wrong.

Categories