tags:

views:

564

answers:

6

Hi, I think it has to be an easy question but I have been searching around and have not found the answer anywhere.

The think is that I have an html page with some scripts (in the body) like this one:

<script type="text/javascript">grf();</script>

The grf() function is defined in an external .js file. The question is: is this function executed once the browser has loaded the page AND all of its external js files? Or it can be the case that the function is executed before the .js files are loaded? And if so, how can I prevent this?

+6  A: 

The method will be executed as the browser is loading the page, when it reaches the end of that <script> block. If the external JS file is included in the page further down than where this method is called, it will throw an error (method not defined).

If you want to wait until the page and assets have been loaded, it's best to use a library. Using the built-in onload event suggested is limited, because it only supports adding one handler (adding another will overwrite the previous one). Here's an example using jQuery:

<script type="text/javascript">
$(document).ready(function() {
   //code goes here
   });
</script>
Rex M
+9  A: 

The function is run when it is encountered. If you want it to run after the page has loaded, the standard method is to hook the onload event of the window. JQuery has great support for this, but lets start with ground-level:

<script type="text/javascript">window.onload = function() { grf(); }</script>

This will stomp on any other onload handlers than may have been assigned previously on the page, which is why most people use JQuery which is careful to chain to previous handlers:

<script type="text/javascript">$(document).ready(function() { grf(); });</script>

Of course for this second example, you need to include the jquery js libraries further up the page (which it sounds like you're not in a position to do?)

Hope this helps,

-Oisin

x0n
+1 for providing a non-jQuery example as well
Jonathan Fingland
The function is run then its *call* (`grf()`) is encountered.
Gumbo
How does this answer the question?..
levik
@levik how does it *not* ?
x0n
@Jonathan Fingland - yes, great for including a non-jQuery example, but the question said nothing about jQuery. Is jQuery just assumed now?
Tim Down
@timdown the question was so basic, it was assumed jquery was out of the realm.
x0n
The question seems to be about whether slow async loading of a sourced script can create a situation where its functions are not available. The answer should be that since script loading loading is synchronous this is not an issue.
levik
The question is not very well worded, but I think this is the best attempt at reading the OP's mind
Juan Mendes
+3  A: 

Browser executes it when it sees the tag. Not only other scripts might not be loaded yet, DOM might not be constructed. However, it is guaranteed that scripts are executed in order they appear in the HTML.

If you can use jQuery, it has $.ready() function, that calls callback when DOM is ready and so every scripts are already loaded. Use it like

$.ready(grf);

or with anonymous function as it commonly used.

vava
+1 Why did this answer got voted down? It’s absolutely legitimate to pass the function directly and not encapsulate it in an additional anonymous function.
Gumbo
@gumbo because it's less clear what's going on - the OP is probably new enough to javascript as it is.
x0n
@gumbo and for the record, I agree with you that it should not be voted down (I +1'd the answer too)
x0n
A: 

The best way to prevent issues with scripts is to use a JavaScript library like jQuery, Mootools etc. which make it easy to bind any code to various events (dom.ready etc.) to make sure everything is loaded fully beforehand.

code_burgar
+5  A: 

As long as the script file is included above the function usage, the function will be available. The browser will halt rendering when it encounters a

<script src="..."></script>

tag. It will only resume processing the document page when the script is downloaded and parsed. So any function defined in the script will be available right after:

<script src="..."></script> <!-- Browser waits until this script is loaded -->
<script>
   foo(); // if function foo was in the script above, it is ALWAYS available now
</script>

This is actually not always a desired behavior - sometimes you don't want to wait for a script to download as it may make your code seem slow. One technique is to have all the scripts load and execute at the bottom of the page before </body>, when all the HTML is already rendered.

levik
+4  A: 

To see if a function is defined:

// functions are defined or undefined just like regular variables function myFunc(){ --code here-- } // So we just need to see if it's defined if( myFunc ){ --do something here-- }; else{ --wait, retry or w/e-- };

When an external script is found, the (x)html will not be read further untill the external script is read (and code inside executed if there's any executable code there).

So, calling a function in an external file after the external file was 'included' cannot generate a function-not-defined error. (However, keep in mind that you WILL get errors if that external function tries to manipulate the DOM or elements that still "don't exist" in the page.)

cuisdy
+1 - For answering this before I did.
James Black
`if (myFunc)` when myFunc is undefined will cause an error. `if (typeof myFunc == "undefined")` won't (as z0n mentioned)
Juan Mendes