Thursday, April 19, 2012

How bad is it to embed JavaScript into the body of HTML?


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?


Source: Tips4all

17 comments:

  1. 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).

    ReplyDelete
  2. 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...

    ReplyDelete
  3. Very good for spaghetti code!

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

    ReplyDelete
  5. 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).

    ReplyDelete
  6. 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.

    ReplyDelete
  7. 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.

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

    ReplyDelete
  9. It is perfectly valid, though it might hurt maintainability. See also http://stackoverflow.com/questions/436411/where-is-the-best-place-to-put-script-tags-in-html-markup and http://stackoverflow.com/questions/436154/why-does-the-call-to-this-jquery-function-fail-in-firefox

    ReplyDelete
  10. 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.

    ReplyDelete
  11. A few things:


    It's completely valid code-wise.
    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.

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

    Now this is a tutorial site 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.

    ReplyDelete
  13. 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.

    ReplyDelete
  14. 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!

    ReplyDelete
  15. 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.

    ReplyDelete
  16. 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.

    ReplyDelete
  17. It is valid to add in body but IE really doesnt likes it.
    so to be on safer side make sure you have your scripts inside tag.

    that was really creating havoc ( especialy for IE ) in the project which we are working on

    ReplyDelete