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>
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>
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>
body
? At least it make code cleaner im most IDEs. –
Succinctorium <script src="..." defer>
, which works in all major browsers (albeit with a potentially breaking bug in IE9 and lower). –
Adorno body
element, before the closing </body>
tag, not after it. https://mcmap.net/q/111396/-put-scripts-at-the-bottom –
Epizoon script
tags had a event
attribute that could be defined to determine when to parse the script. So you have event="load" event="DOMContentLoaded"
for running the script after the DOM is created or event="beforeunload"
on the window beforeunload
event. Example, <script src="scripts/main.js" event="DOMContentLoaded"></script>
. Also, if we have a head
section why don't we have a tail
section (or foot
section)? That would solve the wait until DOM is created issues. –
Threemaster Only comments and the end tag for the html element are allowed after the end tag for the body.
You can confirm this with the specification or a validator.
Browsers may perform error recovery, and the HTML specification even describes how to recover in that situation, but you should never depend on that.
It is also worth noting that the usual reason for putting the script element at the end is to ensure that elements the script may try to access via the DOM exist before the script runs.
With the arrival of the defer
attribute we can place the script
in the head and still get that benefit while also having the JS be downloaded by the browser in parallel with the HTML for better performance.
defer
only applies to external script files (i.e. you must also specify src
attribute). You cannot "defer" a <script>
element that contains script. –
Aquinas 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;
...
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.
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.
(The body and html element end tags could be omitted without trouble; any spaces after those get parsed into the body element anyway.)
See html.spec.whatwg.org/multipage/syntax.html. –
Threemaster 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>
script
tags had a event
attribute that could be defined to determine when to parse the script. So you have event="load" event="DOMContentLoaded"
for running the script after the DOM is created or event="beforeunload"
on the window beforeunload
event. Example, <script src="scripts/main.js" event="DOMContentLoaded"></script>
. –
Threemaster 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.
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>
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:
To be safe, you can:
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>
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>
body
element. That Google article doesn't advise anyone to do any such thing. –
Phelia © 2022 - 2024 — McMap. All rights reserved.