3

Let us say I have a HTML page that contains a javascript file:

The base.js is like this:

$(document).ready(function () {
   obj.init();
}

// ..............

var obj = {...};

Surprisingly, sometimes(not all the time) Firebug shows me the undefined error on obj.init() call! My understanding is that document ready means all html elements, including images, javascript files downloaded and executed(?).

I believe in order to find the root cause of this error, we need understand what exactly the "document ready" means? anybody has any insight?

============================

Update: maybe I should not mention about image over here, my main concern is regarding the javascript file in particular. Does "DOM fully constructed" include "all javascript code executed"?

============================

Update again: It seems people here agreed that event "document.ready" WILL NOT be triggered until ALL javascript code got downloaded and executed. Thus, root cause of the issue remain unknown. I did bypassed this issue after I moved the $(document).ready block to the bottom of the javascript file.

curiousman
  • 57
  • 1
  • 1
  • 7

3 Answers3

6

From the documentation of jQuery.ready():

While JavaScript provides the load event for executing code when a page is rendered, this event does not get triggered until all assets such as images have been completely received. In most cases, the script can be run as soon as the DOM hierarchy has been fully constructed. The handler passed to .ready() is guaranteed to be executed after the DOM is ready, so this is usually the best place to attach all other event handlers and run other jQuery code. When using scripts that rely on the value of CSS style properties, it's important to reference external stylesheets or embed style elements before referencing the scripts.

In cases where code relies on loaded assets (for example, if the dimensions of an image are required), the code should be placed in a handler for the load event instead.

Community
  • 1
  • 1
Tadeck
  • 132,510
  • 28
  • 152
  • 198
  • "While JavaScript provides the load event for executing code when a page is rendered, this event does not get triggered until all assets such as images have been completely received.". here "this event" refer to "load" event, not "ready" event, am I right? it didn't mention about external javascript file though.. – curiousman Feb 29 '12 at 20:41
  • @user1240869: Yes, the documentation specifically answers your question about what exactly "document ready" means and how it differs from event executed when all the files are loaded. `ready` is actually an event specific to jQuery (as explained [here](http://stackoverflow.com/a/3698214/548696)), but `onload` is actually built-in into the JavaScript (see it on the list [here](https://developer.mozilla.org/en/DOM/DOM_event_reference)). The jQuery's `ready` is very close to [`DOMContentLoaded`](https://developer.mozilla.org/en/DOM/DOM_event_reference/DOMContentLoaded) (see compatibility list). – Tadeck Feb 29 '12 at 21:06
  • Thanks for the reference to "DOMContentLoaded", it answered my questions regarding images, style sheet loading while document.ready event handler triggered, But again, it didn't answer my question regarding javascript code! my understanding is that DOM will NOT be fully constructed UNTIL all javascript code downloaded and executed! am I right? – curiousman Feb 29 '12 at 21:21
  • @user1240869: As far as know, yes. Unless, of course, some JavaScript will not be loaded because of error. So, basically, until the JavaScript files stop loading (due to the fact they have been loaded or due to the fact their loading has been aborted), the event should not be triggered. – Tadeck Feb 29 '12 at 21:29
  • @user1240869: Yes, even if the document is downloaded, it's not parsed until the Javascript files are downloaded and executed. – Guffa Feb 29 '12 at 21:36
  • so, Tadeck, based on your understanding, then my code above should not have any problem, right? I simplify the code 'cause real code has thousands of lines. the issue is randomly happening and I bypassed this issue after I moved the document.ready block to the end of javascript file. so I intend to believe it's caused by some bugs inside the javascript engine instead. – curiousman Feb 29 '12 at 21:41
  • Thank you, Guffa, I deliberately use the term "downloaded and executed" instead of "loaded", since there are two phases involved. although I do think browser will execute javascript code as soon as it downloaded. – curiousman Feb 29 '12 at 21:44
2

The ready event happens when the document is loaded and parsed.

This includes all Javascript files, but not images.

The ready event happens after the document is parsed. Some browsers have a specific event for this, in other browsers jQuery uses a timer that polls the status of the document. This means that the event happens either as soon as the entire document is parsed, or slightly later, depending on the browser. This is normally not a problem, as it doesn't happen before anything of the document is parsed.

If you need all images to be loaded before you do something, you should use the load event instead.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • do you have any source to support what you said over here? such as "This includes all Javascript files, but not images."? if I understand you correctly, in this case, how do you explain that firebug will report "undefined" error for variable object? – curiousman Feb 29 '12 at 20:34
  • +1 Very good and detailed answer. There is also another answer to that question, also posted by you, Guffa: http://stackoverflow.com/a/3698214/548696. `ready` just simplifies determining the moment when the DOM is ready. – Tadeck Feb 29 '12 at 21:09
1

You should define obj before referencing it.

Also, document.ready doesn't mean that the resources will be loaded, only that the document been parsed, so the resources load between document ready and the $(window).load event.

FishBasketGordo
  • 22,904
  • 4
  • 58
  • 91
meder omuraliev
  • 183,342
  • 71
  • 393
  • 434
  • obj is defined underneath the document.ready block, so this is not the issue. – curiousman Feb 29 '12 at 20:31
  • `$(document).ready(function () { obj.init(); }); var obj = {};` would result in Cannot call method `init` of undefined because `obj` is NOT defined in the scope of the function which you provide to jQuery's ready method. **How** isn't this the issue? Please provide **real code**. From **your** code and error reported, it sounds like you are mistaking document ready which is a DOM event to referencing objects which have not been defined in the scope. – meder omuraliev Feb 29 '12 at 20:41
  • var obj is defined outside of function, so it's part of window object, that's why I can reference it within the document ready. – curiousman Feb 29 '12 at 21:50
  • But is it defined `before` you reference it? No. Reference it before and you won't get undefined method because the object **at that point in time** doesnt exist.. assuming you are still dealing with "Firebug shows me the undefined error on obj.init() call!" is the error.... – meder omuraliev Feb 29 '12 at 22:14