el_pup_le
el_pup_le

Reputation: 12179

Loading order for script inside body and using jquery ready

I've got a script inside a body tag. Problem is some code is being loaded before it is finished even though it is in a document ready block. Shouldn't the code in the ready block wait for code in the script tag to finish? Or does it only hold off until the script tag is rendered but not executed?

<html>
<head>
  <script data-main="script.js" src="/assets/js/require.js"></script>
</head>
<body>
  <script type="text/javascript">
    var foo = ${fromServer};

  </script>
</body>
</html>

script.js: And I expect this to wait for until script is complete...

$(function() {
  // access script var from here, not set yet hmmmm
});

I'd love to know what is going on here...

Update:

Okay now, here is the variable from the page

  require.config({
        baseUrl: '/assets/js/app',
        shim: {
            d3: {
                exports: 'd3'
            },
            underscore: {
                exports: '_',
            },
            backbone: {
                deps: ['underscore', 'jquery'],
                exports: 'Backbone'
            },
            uidate: {
                deps: ['jquery']
            }
        },
        paths: {
            d3: '../lib/d3.v3',
            jquery: '../lib/jquery-2.0.3.min',
            underscore: '../lib/underscore',
            backbone: '../lib/backbone'

        }
    });

require([...], function(...) {
  //console.log here and foo is set and good to go
  var myCollection = new MyCollection(foo);

inside MyCollection:

// define(.... {
// var coll = Backbone.Collection.extend({

initialize: function() {
  console.log(this);
}

Looking at the console I see:

 {length: 0, models: Array[0], _byId: Object, constructor: function, model: function…}

When I expand the object in Chrome console there are actually models in there.... strange. If I do a setTimeout inside init and console.log(this) again the models are set. Where is this delay of initialising the models coming from?

I've also tried just loading an array like:

var someColl = new MyCollection([ { ... }, { ... } ]);

Same problem here too.

Update: I've tried to narrow down the scope of the problem, console.log prints an empty array here

var testing = [{x:1,d:2},{x:3,d:8},{x:3,d:98}];
var myCollection = Backbone.Collection.extend({
    initialize: function() {
        console.log(JSON.stringify(this));
    }
});
var x = new myCollection(testing);

Upvotes: 1

Views: 1863

Answers (1)

jfriend00
jfriend00

Reputation: 707336

jQuery ready waits for the DOM to finish loading before calling its callback. This will be roughly equivalent to when the </body> tag is parsed and everything in front of it (including any scripts) has already been parsed. Scripts that are not marked defer or async will have already run.

It isn't entirely clear from your question what exactly your problem is, but code inside a jQuery ready block will be executed after other scripts in the <head> or <body> are executed.

If you are loading scripts asynchronously with the require.js library, then those scripts may load BEFORE or AFTER the document is ready depending upon what else is happening in the document loading. If you need to coordinate timing with when those scripts are loaded asynchronously, then you will have to use the capabilities in the require.js library in order to know when those scripts are loaded or use document.ready in those scripts to make sure they wait for the rest of the document to be parsed.

Upvotes: 2

Related Questions