flyingL123
flyingL123

Reputation: 8076

document.head and document.getElementsByTagName("head")[0] strange behavior

I can't figure out what's wrong with this code. After defining a script like this:

var script = document.createElement('script');
script.src = 'http://example.com/file.js';
script.type = 'text/javascript';
script.onload = function(){
    //code to execute after script loads
}

I then have the following line:

(document.head || document.getElementsByTagName("head")[0]).appendChild(script);

For some reason, I am getting very odd inconsistent behavior where it seems that the onload function is being called before the file.js is actually loaded. There are variables contained in file.js that I use in the onload function, and every so often, the function executes before those variables are defined according to the error console.

If I change the last line to:

document.head.appendChild(script);

Or

document.getElementsByTagName("head")[0].appendChild(script);

The problem seems to go away.

The problem also goes away if I assign it to a variable before appending:

var head = document.head || document.getElementsByTagName("head")[0];
head.appendChild(script);

Why is this happening?

Upvotes: 2

Views: 3090

Answers (1)

Paul
Paul

Reputation: 141839

It's caused by a missing semicolon:

script.onload = function(){

}; // Add this semicolon and it will be fixed

Without that semicolon the interpreter parses your next set of parenthesis as though you are immediately invoking that anonymous function and then attempting to call appendChild on that function's return value. It's interpreted like so:

script.onload = (function(){
    //code to execute after script loads
}(document.head || document.getElementsByTagName("head")[0])).appendChild(script);

Which will certainly throw an error after executing your anonymous function (unless that function actually returns an object which has an appendChild function).

Upvotes: 4

Related Questions