views:

500

answers:

16

A team that I am working on has gotten into the habit of using <script> tags in random places in the body of our HTML pages. For example:

<html>
    <head></head>
    <body>
        <div id="some-div">
            <script type="text/javascript">//some javascipt here</script>
        </div>
    </body>
</html>

I had not seen this before. It seems to work in the few browsers that I've tested. But as far as I know, it's not valid to put script tags in places like this.

Am I wrong? How bad is it that we are putting script tags within div tags like this? Are there any browser compatibility issues I should be aware of?

+2  A: 

Very good for spaghetti code!

François
+1  A: 

It's certainly legal, I've seen it on a few pages here on Exforsys and here on w3schools for example.

Now both are tutorial sites showing the basics of HTML and Javascript so in that context it's perfectly understandable. However, I wouldn't like to see it in production code for anything more than a simple statement or two. Without seeing what you've replaced by //some javascipt here I wouldn't like to comment.

There shouldn't be any browser issues with this though.

ChrisF
+3  A: 

Actually, it's quite common. For example Google's analytics tracking code uses just this syntax:

<script type="text/javascript">
  var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
  document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>

If it's good enough for Google...

Keltex
-1 - just because Google is doing it does not mean it is good practice. Common != good.
Jason
Google Analytics is overly convoluted anyway and their usage of JavaScript for tracking is actually a good example of overengineering.
Esko
also, they recommend that you put the script at the bottom of the page, not in the middle, which is where scripts should be placed if you have to place them. NOT in the header where people usually put them
Jason
What's exactly wrong with it? It's valid.
Keltex
Off-topic aside: I'm always irritated by Google's needless and bizarre use of `unescape`, given that `escape`/`unescape` Is Evil (and that `\x3C` would have been a much simpler way of doing it).
bobince
@Keltex: The code isn't invalid, however claiming that it's good practice just because some people use it is not a valid argument.
Matti Virkkunen
@bobince - nothing prevents you from "hardcoding" the script tag with reference to ga.js yourself. After all this shows just how apt to cut-n-past developers are without thinking about what is actually going on.
Peter Lillevold
+3  A: 

It is valid and, depending on your server-side framework and the nature of the code, sometimes very difficult to avoid.

Pointy
+1  A: 

However, it's also good in that you know the JS needed for a section of HTML is going to be their for it. Rather than having to assert and build up some inclusion at the top of the file.

So, rather than "if you're going to use this HTML, make sure you import xyz.js" you can just include the HTML and be done with it.

So, it's not necessarily horrible evil. Perhaps not spectacularly awesome, but not utterly terrible either. Kind of depends on the intent.

Will Hartung
+1  A: 

see yahoo ui for best practice : http://developer.yahoo.com/performance/rules.html (javascript at the bottom of the page)

+17  A: 

It's perfectly valid.

You wouldn't want to put great big blocks of code mixed up in the markup there (better to use external scripts), but it can be useful to:

  • add extra binding information for progressive-enhancement (where that data is difficult to fit into a classname or other approach to hiding extended information in attributes); or

  • where it's necessary to kick off a scripted enhancement as quickly as possible (rather than waiting for window-load/document-ready). An example of this would be autofocus, which can irritate if fired too late.

You may be thinking of <style> elements, which aren't allowed in <body> (although most browsers allow it nonetheless).

bobince
+1 for the autofocus; sometimes I'm on a slow connection and it's not fun to be already somewhere else (in the worst case: typing a password) when being put back to the first field.
Marcel Korpel
+2  A: 

A few things:

  1. It's completely valid code-wise.
  2. It's completely unrecommended.

Doing this slows down your page load considerably as the Javascript must execute before any of the rest of the page can render. If you're doing a lot of work in that Javascript, your browser could hang. You should try to (whenever possible) load your Javascript dynamically and at the end of your page (preferably before the </body> tag)

Purchase and read High Performance Javascript. It will change the way you write JS.

Jason
*shakes head at neg vote* sigh
Jason
Not my downvotes, but when I think Yahoo, I think `YAHOO.util.Event.addListener`, not efficient/concise javascript. I wouldn't read a book and treat it as gospel, sometimes you **must** have javascript in the page itself, e.g. a variable dynamically rendered, something you can't do in an external `.js`.
Nick Craver
have you read the book? if you had, you'd know that it teaches optimization techniques. things like `YAHOO.xx.xx.xx` are cached locally. on occasion, yes it's ok to render a variable on the page, but that can usually be done externally anyways if you just set a hidden input value from the server. but i said it is *unrecommended* not *wrong*. also, nicholas zakas, the author, knows his shit, regardless of who his employer is.
Jason
+1  A: 

it is valid!

you can use:

<script type="text/javascript">
//<![CDATA[

// some javascrpt code that perfectly validates in the w3c validator

//]]>
</script>

i don't think you can say if it is a bad practice in general. You have to tell in the case. But sure is that it is good to have all your JS at the same place. Its a little messy if you have little pieces of JS all over your html file.

meo
it is a bad practice in general.
Jason
ok just read you post, good to know. I never do it anyway, but never though that it could make hang your browser... ...how it comes?
meo
Any JavaScript can hang your browser (sometimes I still get those alert boxes in Firefox with an ‘Abort script’ and a ‘Continue script’ option).
Marcel Korpel
this is true, any JS can hang your browser. however, if you're going to hang it (obv never recommended), better to do it once the page has fully rendered with content and the user can begin reading/interacting with the page. the reason why JS hangs your browser is because it runs synchronously, meaning that the browser must wait until the JS is completely executed before it continues rendering, since it doesn't know what the JS is going to do. While it's waiting, it is not rendering, making it look like it's hanging.
Jason
A: 

The oft-stated recommendation that scripts should be kept in the header is to ensure that the script is loaded before it is called. This is only an issue for certain event handlers. For other types of script, it doesn't matter, and for some types (such as document.write), it doesn't make any sense.

Tor Haugen
+2  A: 

I prefer to put references to external scripts into the head, and scripts that start things up and initialize widgets and whatnot into the body.

An issue that's very easy to run into is that a script element in the body cannot access elements that come after it. Also, a related nasty browser compatibility issue is the fact that IE doesn't allow script elements to modify the element they're in. So if you have this:

<div id="foo">
  <script type="text/javascript">
    document.getElementById("foo")... // do something to it
  </script>
</div>

IE is not going to like your page. Old versions of IE used to give very cryptic error messages for this or even blank the entire page, but IE8 seems to give a descriptive error message.

As long as you make sure that your scripts only access DOM that's safe to access, I don't think it's evil to put script elements into the body. In fact, IMHO, putting scripts that initialize widgets after the related elements can be more readable than putting everything in one place (and I believe this might also make them run earlier, which makes stuff jump around less as the page loads).

Matti Virkkunen
A: 

it's one of many, many best practices that's as much about improving performance as it is about improving your approach to programming. ultimately in web development getting the product out matters the most!

heydenberk
+2  A: 

As several people mentioned, its valid, it works, and it is widely used.

Best practices as far as semantics recommend (or at least used to recommend) is placing script tags inside of the header.

More modern best practices which take performance into account recommend placing script tags (external and inline) at the bottom right before the body tag, to allow the markup to render completely before any javascript executes.

For easier to understand and maintain code, "unobtrusive javascript" is recommended, where the code is in an external file and binds events to the DOM. (Google unobtrusive javascript)

One case where its useful to have javascript inline is to initialize variables with values that only exists server side, which will then later be used by the external javascript code.

Gal
A: 

I assume that your team is doing this either because they want to insert script dynamically, or that they are writing script that will fire at page load.

I wouldn't say there's anything wrong with doing this when ABSOLUTELY NECESSARY, (as long as it's in a CDATA block), but outside of that, I would recommend to your team that they use a script library like prototype or jQuery, and keep the scripts external to the page. This is usually cleaner, and libraries will sometimes force a bit of cleanliness to the code, which I would bet isn't happening currently.

I also wouldn't run any time-consuming functions in inline script tags, as these happen on page load, and as Jason stated above, could slow the load of the page. All script libraries have neat functions that allow you to do things on load of the page, and will give you the option of when in the page load to fire them, such as after the dom is loaded.

Jesse
A: 

If you have an editor that can handle both html and javascript syntax simultaneously. And if you like to first read few lines of html and then javascript.. sure. go for it.

Cheery