Is it wrong to place the <script> tag after the </body> tag?

JavascriptHtml

Javascript Problem Overview


How wrong is it to place the script tag after the closing tag of the body (</body>)?

<html>
  ....
  <body>
     ....
  </body>
  <script type="text/javascript" src="theJs.js"></script>
</html>

Javascript Solutions


Solution 1 - Javascript

It won't validate outside of the <body> or <head> tags. It also won't make much difference — unless you're doing DOM manipulations that could break IE before the body element is fully loaded — to putting it just before the closing </body>.

<html>
  ....
  <body>
     ....
     <script type="text/javascript" src="theJs.js"></script>
  </body>
</html>

Solution 2 - Javascript

Yes. Only comments and the end tag for the html element are allowed after the end tag for the body.

Browsers may perform error recovery, but you should never depend on that.

Solution 3 - Javascript

As Andy said, the document will be not valid, but nevertheless the script will still be interpreted. See the snippet from WebKit for example:

void HTMLParser::processCloseTag(Token* t)
{
    // Support for really broken HTML.
    // we never close the body tag, since some stupid web pages close it before
    // the actual end of the doc.
    // let's rely on the end() call to close things.
    if (t->tagName == htmlTag || t->tagName == bodyTag
                              || t->tagName == commentAtom)
        return;
    ...

Solution 4 - Javascript

Internet Explorer doesn't allow this any more (since version 10, I believe) and will ignore such scripts.

Firefox and Chrome still tolerate them, but there are chances that some day they will drop this as non-standard.

Solution 5 - Javascript

Procedurally inserting an "element script" after an "element body" is a "parse error" by the recommended process by W3C. In "Tree Construction" create an error and run "tokenize again" to process that content. So it's like an additional step. Only then can it run the "Script Execution" - see the scheme process.

> Anything else is a "parse error". Switch the "insertion mode" to "in body" and reprocess the token.

Technically, by the browser, it's an internal process how they mark and optimize it.

Solution 6 - Javascript

Yes. But if you do add the code outside it most likely will not be the end of the world since most browsers will fix it, but it is still a bad practice to get into.

Solution 7 - Javascript

Google actually recommends this in regards to 'CSS Optimization'. They recommend in-lining critical above-fold styles and deferring the rest (CSS file).

Example:

<html>
  <head>
    <style>
      .blue{color:blue;}
    </style>
    </head>
  <body>
    <div class="blue">
      Hello, world!
    </div>
  </body>
</html>
<noscript><link rel="stylesheet" href="small.css"></noscript>

See: Optimize CSS Delivery

Solution 8 - Javascript

Modern browsers will take script tags in the body like so:

<body>
    <!-- main body content -->
    <script src="scripts/main.js"></script>
</body>

Basically, it means that the script will be loaded once the page has finished, which may be useful in certain cases (namely DOM manipulation). However, I highly recommend you take the same script and put it in the head tag with "defer", as it will give a similar effect.

<head>
    <script src="scripts/main.js" defer></script>
</head>

Solution 9 - Javascript

You can place it like the below, or also inside the head tag is fine, but regular practice is something like just before the end of the </body> naming a comment for easy use later, and opening a <script>putting any JS inside</script></body></html>.

    <script>
      window.addEventListener('DOMContentLoaded', event => {

        // Activate Bootstrap scrollspy on the main nav element
        const sideNav = document.body.querySelector('#sideNav');
        if (sideNav) {
          new bootstrap.ScrollSpy(document.body, {
            target: '#sideNav',
            offset: 74,
          });
        };

        // Collapse responsive navbar when toggler is visible
        const navbarToggler = document.body.querySelector('.navbar-toggler');
        const responsiveNavItems = [].slice.call(
          document.querySelectorAll('#navbarResponsive .nav-link')
        );
        responsiveNavItems.map(function (responsiveNavItem) {
          responsiveNavItem.addEventListener('click', () => {
            if (window.getComputedStyle(navbarToggler).display !== 'none') {
              navbarToggler.click();
            }
          });
        });
      });
    </script>

    <!-- Bootstrap core JS-->

    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>

</body>

</html>

Solution 10 - Javascript

 <script>
    window.addEventListener('DOMContentLoaded', event => {

      // Activate Bootstrap scrollspy on the main nav element
      const sideNav = document.body.querySelector('#sideNav');
      if (sideNav) {
        new bootstrap.ScrollSpy(document.body, {
          target: '#sideNav',
          offset: 74,
        });
      };

      // Collapse responsive navbar when toggler is visible
      const navbarToggler = document.body.querySelector('.navbar-toggler');
      const responsiveNavItems = [].slice.call(
        document.querySelectorAll('#navbarResponsive .nav-link')
      );
      responsiveNavItems.map(function (responsiveNavItem) {
        responsiveNavItem.addEventListener('click', () => {
          if (window.getComputedStyle(navbarToggler).display !== 'none') {
            navbarToggler.click();
          }
        });
      });
    });
  </script>
  <!-- Bootstrap core JS -->
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>

Always end with a body tag and make sure every single JavaScript part is within the body tag. You can also have links or scripts inside head tags, but it is not recommended unless you are really certain your JavaScript code is too big to have it inline.

Solution 11 - Javascript

Technically you shouldn't be able to place the script tag after the body tag since rendering of the page content ends with the body (or is it the head?.)

But browsers are somewhat fault tolerant (although I wouldn't depend on this as a universal truth because you just might never know) and they'd:

  1. move the script tag back into the body tag if it appears outside the body or html tag.
  2. move the script tag into the head tag if it appears before the document declaration.
  3. leave it as is if it appears (in source order) anywhere else it appears in the document.

To be safe, you can:

  1. use the defer or async attribute with the script tag in the head, or
  2. use the script tag(s) right before the closing body tag

This norm is an accepted practice/convention and is guaranteed to remove any doubts.

Also while you are play safe and do the most [reasonable] thing, keep in mind that what you need to [then] worry about is the performance because the loading/downloading, parsing and interpretation of the internal/external sourced file(s) is/are dependent on where the script(s) tag occurs, even if you were using defer or async.

<!-- Moved (prepend) into the head -->
<script>console.log(1);
</script>
<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<!-- Remains where it is -->
	<script>
		console.log(2);
	</script>
	<title>Document</title>
</head>

<body>
	<h1>Content goes here</h1>
	<!-- Remains where it is -->
	<script>
		console.log(3);
	</script>
	<h1>Content goes here</h1>

	<!-- Remains where it is -->
	<script>
		console.log(4);
	</script>
</body>

</html>
<!-- Moved (append) into the body -->
<script>
	console.log(5);
</script>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDanCView Question on Stackoverflow
Solution 1 - JavascriptAndy EView Answer on Stackoverflow
Solution 2 - JavascriptQuentinView Answer on Stackoverflow
Solution 3 - JavascriptVitalii FedorenkoView Answer on Stackoverflow
Solution 4 - JavascriptBronxView Answer on Stackoverflow
Solution 5 - JavascriptBGBRUNOView Answer on Stackoverflow
Solution 6 - JavascriptTaylor SatulaView Answer on Stackoverflow
Solution 7 - JavascriptDonald PorterView Answer on Stackoverflow
Solution 8 - JavascriptAd CharityView Answer on Stackoverflow
Solution 9 - JavascriptKushal PokhrelView Answer on Stackoverflow
Solution 10 - JavascriptKushal PokhrelView Answer on Stackoverflow
Solution 11 - JavascriptAdebiyi AdedotunView Answer on Stackoverflow