47

I read that you should define your JavaScript functions in the <head> tag, but how does the location of the <script> (whether in the <head>, <body>, or any other tag) affect a JavaScript function.

Specifically, how does it affect the scope of the function and where you can call it from?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mark Rogers
  • 96,497
  • 18
  • 85
  • 138

9 Answers9

29

Telling people to add <SCRIPT> only in the head sounds like a reasonable thing to do, but as others have said there are many reasons why this isn't recommended or even practical - mainly speed and the way that HTML pages are generated dynamically.

This is what the HTML 4 spec says :

The SCRIPT element places a script within a document. This element may appear any number of times in the HEAD or BODY of an HTML document.

And some sample HTML. Doesn't it look pretty all formatted here :)

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
     "http://www.w3.org/TR/html4/strict.dtd">
<HTML>
<HEAD>
<TITLE>A document with SCRIPT</TITLE>
<META http-equiv="Content-Script-Type" content="text/tcl">
<SCRIPT type="text/vbscript" src="http://someplace.com/progs/vbcalc">
</SCRIPT>
</HEAD>
<BODY>
<SCRIPT type="text/javascript">
...some JavaScript...
</SCRIPT>
</BODY>
</HTML>

And something to look forward to in HTML 5 :

New async attribute in <SCRIPT> :

Note: There are ways [sic] a script can be executed:

The async attribute is "true": The script will be executed asynchrously with the rest of the page, so the script will be executed while the page continues the parsing.

The async attribute is "false", but the defer attribute is "true": The script will be executed when the page is finished with the parsing.

Simon_Weaver
  • 140,023
  • 84
  • 646
  • 689
  • 1
    @m4bwav - i mainly wanted to make the additional point that hadn't been made that that it is OK to put SCRIPT in BODY for anyone who thought they shouldn't. in addition the Yahoo 'performance rules' article mentioned is well worth reading and covers the issue thoroughly – Simon_Weaver Feb 03 '09 at 17:47
  • 11
    Just seeing all the tags being written in caps makes the credibility of this answer fall greatly... – Seb Nilsson Mar 21 '12 at 12:54
  • 11
    The code with the capitalized tags is a direct copy/paste from the [W3.org spec](http://www.w3.org/TR/REC-html40/interact/scripts.html). – Homer Oct 22 '12 at 20:28
  • Your link is broken. Is it suppose to be the source of that "quote" explaining the use of async attribute? Regardless of the source, it's quite confusing way of saying it, since it gives the impression that one ought to set the attributes value to "true" or "false". However, the async attribute does not support values "true" nor "false". Its simple presence implies "true", e.g. ` – Timo Nov 12 '13 at 14:08
  • 2
    @SebNilsson I wanted to know if it is ok to put script tags in the body section. This answer says I can, so, why do the caps detract from it's credibility? – Dave Becker May 27 '14 at 13:46
19

The normal rules of play still stand; don't use stuff before it's defined. :)

Also, take note that the 'put everything at the bottom' advice isn't the only rule in the book - in some cases it may not be feasible and in other cases it may make more sense to put the script elsewhere.

The main reason for putting a script at the bottom of a document is for performance, scripts, unlike other HTTP requests, do not load in parallel, meaning they'll slow down the loading of the rest of your page. Another reason for putting scripts at the bottom is so you don't have to use any 'DOM ready' functions. Since the script tag is below all elements the DOM will be ready for manipulation!

EDIT: Read this: http://developer.yahoo.com/performance/rules.html#js_bottom

James
  • 109,676
  • 31
  • 162
  • 175
  • adding at the bottom affects seo as well, I'm told – Mark Rogers Jan 30 '09 at 21:11
  • @MarkRogers, you said it affects seo. does it affect seo in a good way or a bad way? thanks – Brian Sep 22 '13 at 09:26
  • 2
    @Brian - I asked Jennyfofenny about this, and she said that it's better if the javascript loading occurs at the end of the file. This way the context can be loaded and indexed first, allowing the page to be indexed more easily and for the page content to load more naturally. – Mark Rogers Sep 23 '13 at 17:08
9

One of the aspects of placement is performance. See this fine article within the YSlow discussion for why it's sometimes recommended you put them at the bottom of the document.

As for issues of scope, the usual visibility rules for Javascript (vars defined inside or outside of functions, local, global, closures, etc.) are not affected so far as I know.

Alan
  • 3,815
  • 1
  • 26
  • 35
4

Position of script tag does matter. If you bind a Function with document Element then the document element has to be loaded first before we implement function. suppose getTeachers() is function in getTeachers.js file. This will give you an error:

<html xmlns="http://www.w3.org/1999/xhtml">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Unit Teachers</title>
<head>
 <script type="text/javascript" src="getTeachers.js"></script>
 <script type="text/javascript">
document.getElementById("buttonId").onclick=function(){getResults()};

</script>
 </head>
 <body>
 <form>
 <input type = "button" id="buttonId" value = "Press for Results"  /><br />
 </form>

<span id="results" /></span>
</body>
</html>

It gives error before head is loaded first and it cannot find element with id specified. The below code is correction:

<html xmlns="http://www.w3.org/1999/xhtml">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Unit Teachers</title>
<head>
 <script type="text/javascript" src="getTeachers.js"></script>

 </head>
 <body>
 <form>
 <input type = "button" id="buttonId" value = "Press for Results"  /><br />
 </form>
<script type="text/javascript">
document.getElementById("buttonId").onclick=function(){getResults()};

</script>
<span id="results" /></span>
</body>
</html>
Dhwaneel
  • 541
  • 5
  • 8
3

If your script refers to an ID on the page and the page has not been rendered (i.e. script is before HTML, or your script is executed with onload, rather then the DOM is ready) you can also get an error.

Diodeus - James MacFarlane
  • 112,730
  • 33
  • 157
  • 176
2

It doesn't. Most programming framework scatter scripts all throughout the page. I've only rarely seen problems because of that (and only from older browsers).

TheSmurf
  • 15,337
  • 3
  • 40
  • 48
2

If you pull Javascripts in through XMLHttpRequest, like Diodeus said, it probably won't work. In my case, there was no error, the browser just ignores the new script(s).

I ended up using this, not terribly elegant but works for me so far:

http://zeta-puppis.com/2006/03/07/javascript-script-execution-in-innerhtml-the-revenge/

How to use execJS: http://zeta-puppis.com/2006/02/23/javascript-script-execution-in-innerhtml/

Note: Watch out for &lt; in this line: for(var i=0;i<st.length; i++)

PJ Brunet
  • 3,615
  • 40
  • 37
1

If you have an inline script (outside functions) located before functions it may call, you may get an error because they may not be not available yet. Not saying it is always going to happen, just that it may depending on browser type or version.

Otávio Décio
  • 73,752
  • 17
  • 161
  • 228
1

Javascript's scoping rules are similar to perl - you can call any function at the current or any higher scope level. The only restriction is that the function has to be defined at the time you call it. The position in the source is irrelevant - only the position in time matters.

You should avoid putting scripts in the <head> if possible as it slows down page display (see the link Alan posted).