I just made loading screen with Javascript and am wondering which part of HTML Document it must be placed.
I mean on inside of or before closing tag???
Some documents say it must be placed on because it has to be loaded before any contents, but it seems to work well even though I put it before .
Could you tell me which part of HTML Document I "must" or "had better" put the scripts?
Is there difference in case with "defer" or "no defer"??
window.addEventListener('load', function () {
document.querySelector('#js-loading').classList.add('hide');
});
.loading {
opacity: 1;
transition-property: visibility, opacity;
transition-duration: 0.2s;
}
.loading.hide {
visibility: hidden;
opacity: 0;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" href="css/style.css">
<script src="js/script.js"></script> //Position A ???
<script src="js/script.js" defer></script> //Position A with defer???
</head>
<body>
<div class="loading" id="js-loading">
<div class="loading-img"><img src="images/loading.svg" alt=""></div>
</div>
<div>content</div>
<script src="js/script.js"></script> //Position B ???
<script src="js/script.js" defer></script> //Position B with defer???
</body>
</html>
The docs (https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script) are saying about the defer attribute:
This Boolean attribute is set to indicate to a browser that the script
is meant to be executed after the document has been parsed, but before
firing DOMContentLoaded.
Scripts with the defer attribute will prevent the DOMContentLoaded
event from firing until the script has loaded and finished evaluating.
Without the defer attribute, the scripts would be loaded immediately.
But in any case and independent of the script tag placement, the scripts will be executed before the load event is fired, so every placement is fine for a script, which adds an event listener to the load event.
Gusto-wise, I would place them in the head part, since that is much more clean, especially if you have much content in the body part.
You can use document.readyState API to know when the document is completely loaded.
You can refer this answer for more insight.
https://stackoverflow.com/a/44715040/7181668
Related
I got a HTML page:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello World</title>
<script src="https://unpkg.com/react#16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom#16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone#6.15.0/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('root')
);
</script>
</body>
</html>
How browser sees the script with type "text/babel" and lets babel transpile the code? When and where JavaScript code appears to be executed by React libraries?
Take a look at the unminified source for Babel.js 6.1.19
Search that file for "text/babel". See where it's used in runScripts()?
That function, which is too long to include here in its entirety, contains comments such as:
/**
* Load, transform, and execute all scripts.
*/
This function is where the magic starts. But how do we launch runScripts? Search for references to that function. It is located in only a few spots:
if (global.addEventListener) {
global.addEventListener("DOMContentLoaded", runScripts, false);
} else if (global.attachEvent) {
global.attachEvent("onload", runScripts);
}
In other words, Babel is attaching runScripts as an event handler for the DOM's onload event. When is that event emitted? Let's check MDN:
The load event fires at the end of the document loading process. At this point, all of the objects in the document are in the DOM, and all the images, scripts, links and sub-frames have finished loading.
There are also Gecko-Specific DOM Events like DOMContentLoaded and DOMFrameContentLoaded (which can be handled using EventTarget.addEventListener()) which are fired after the DOM for the page has been constructed, but do not wait for other resources to finish loading.
https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onload
So, Babel's event handler is run after the DOM has completed loading. All scripts are loaded by this point. At that time, Babel scans the scripts, finds the script tags with the right type, and does its thing.
Having the code below:
<html>
<head>
<script>
function elem_onload() {
console.log("elem_onload");
};
</script>
</head>
<body onload="elem_onload()">
<script type="text/javascript" src="script.js" defer></script>
</body>
</html>
script.js:
console.log("external script");
the defer attribute doesn't seems to work. The output is:
external script
elem_onload
whether with or without defer attribute. Shoudn't it be
elem_onload
external script
with defer defined?
Duplicated answer!?
I'd like to state that my answer isn't duplicate of
How exactly does <script defer=“defer”> work?
The referenced recommended answer is about inline script where the browser behavior is clear for me - it simply ignores defer. My question is about external script in which case the browser should execute the external deferred script
after the document has been parsed
as documentation states hence after onload event.
So I'm waiting for an appropriate answer...
The external script deferred by the defer attribute is executed before the (DOMContentLoaded) is fired, i.e. when the initial HTML document has been completely loaded and parsed. The onLoad attribute on a <body> tag, on the other hand, fires only when a web page is fully loaded.
Therefore, the defer attribute is indeed working. You may test it by trying the two cases below. In both cases the content of script.js file should be this:
console.log(document.getElementById('sample').innerHTML);
CASE 1 HTML - with defer --> logs "Sample text"
<body onLoad="elem_onload()">
<script type="text/javascript" src="script.js" defer></script>
<div id="sample">Sample text</div>
</body>
CASE 2 HTML - without defer --> logs an error
<body onLoad="elem_onload()">
<script type="text/javascript" src="script.js"></script>
<div id="sample">Sample text</div>
</body>
Thx. all for help.
So the statement "...after the document has been parsed" from original doc. (MDN <script> tag)
refers say step #0 from 12.2.6 The end
when document is completely parsed and now there are several tasks to be done on that occasion. Those tasks includes running external deferred scripts which
is prior (#3) to onload event.
Am I right?
Why is $(document).ready needed after the <script> tag?
What would happen if we don't use $(document).ready?
$(document).ready is javascript code, so it has to be written in <script> element and after jQuery is loaded.
If you don't write $(document).ready, your code will not wait for DOM to load completely and execute the javascript code immediately.
If you're using script in <head> that is using/manipulating some elements from DOM, you'll need ready, otherwise you'll get null/undefined.
If you're using script at the end of <body>, then you'll be safe as all the elements are loaded.
Quoting as it is from jQuery Docs
While JavaScript provides the load event for executing code when a page is rendered, this event does not get triggered until all assets such as images have been completely received. In most cases, the script can be run as soon as the DOM hierarchy has been fully constructed. The handler passed to .ready() is guaranteed to be executed after the DOM is ready, so this is usually the best place to attach all other event handlers and run other jQuery code. When using scripts that rely on the value of CSS style properties, it's important to reference external stylesheets or embed style elements before referencing the scripts.
In cases where code relies on loaded assets (for example, if the dimensions of an image are required), the code should be placed in a handler for the load event instead.
Example? Sure!
In Head no ready
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<script>
alert($('#myname').val());
</script>
</head>
<body>
<input type="text" value="Tushar" id="myname" />
</body>
</html>
At the end of body
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<input type="text" value="Tushar" id="myname" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<script>
alert($('#myname').val());
</script>
</body>
</html>
In head with ready
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.0/jquery.min.js"></script>
<script>
$(document).ready(function() {
alert($('#myname').val());
});
</script>
</head>
<body>
<input type="text" value="Tushar" id="myname" />
</body>
</html>
For the <script> at the end of <body>, you can omit ready.
Why is $(document).ready really need after <script> tag when we use javascript.
It isn't.
What else if we don't use $(document).ready
First, understand why people use ready: It's used to delay the code within the function you pass into it until jQuery calls that function, which jQuery does when it thinks the document is fully loaded.
JavaScript code within script tags runs immediately. If the script tag is above an element it refers to, the element won't exist when the script runs:
<script>
$("#foo").show();
</script>
<div id="foo" style="display: none">...</div>
That div will not be shown, because it doesn't exist when the code runs. So people use ready to delay their code.
There's a better way if you control where your script tags go: Just put your script tag at the end of the document, just before the closing </body> tag:
<div id="foo" style="display: none">...</div>
<!-- ... -->
<script>
$("#foo").show();
</script>
</body>
All of the elements defined above the script tag will exist when the code runs. No need for ready.
The ready event occurs when the DOM (document object model) has been loaded.
Because this event occurs after the document is ready, it is a good place to have all other jQuery events and functions.
//Use ready() to make a function available after the document is loaded:
$(document).ready(function(){
$("button").click(function(){
$("p").slideToggle();
});
});
Like in the example above.
The ready() method specifies what happens when a ready event occurs.
Direct quote from Learn jQuery
A page can't be manipulated safely until the document is "ready."
jQuery detects this state of readiness for you. Code included inside
$( document ).ready() will only run once the page Document Object
Model (DOM) is ready for JavaScript code to execute. Code included
inside $( window ).load(function() { ... }) will run once the entire
page (images or iframes), not just the DOM, is ready.
This is probably the weirdest thing I've encountered while programming in JavaScript, and I can't find a solution anywhere online.
So all I've done is created an html document and a JS file that is externally linked to it. When I try to reference an element from the page in the JS file, it doesn't do anything, and there aren't any errors in the console. Here's an example:
$('#box').click(function() {
alert('test');
})
<html>
<head>
<script src="script.js" type="text/javascript"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script> <!--jQuery-->
</head>
<body>
<div id="box" style="width: 200px; height: 100px; background: #000;">
</div>
</body>
</html>
It works wonderfully in the fiddle, but on my machine it doesn't. Also tried hosting on Google Drive, nothing. I opened it on another computer, nada. Here's the live page:
https://7568fa8ec856c21498701e0edd220440c5c75264.googledrive.com/host/0B4rWYiw5-JZtfm1wNE1iMkY1b0tuaXFnaUZmaWFsSU5XLXQtaTh5U2ozVFB0NHgyVXpOOW8/test.html
I don't understand!?!?
How does it behave if you define HTML like below:
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script> <!--jQuery-->
</head>
<body>
<div id="box" style="width: 200px; height: 100px; background: #000;">
</div>
</body>
<script src="script.js" type="text/javascript"></script>
</html>
It is actually recommended to include custom JavaScript after document body.
In addition to fixing your issue, the HTML will be displayed on the page before JavaScript execution will finished.
If scripts.js is using jquery, you need to load the jquery before you load scripts.js
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script> <!--jQuery-->
<script src="script.js" type="text/javascript"></script>
You have two separate issues:
First you must load jQuery before your script so that it is available when your script runs. So, switch the order of your two script tags to fix that issue.
Your script cannot run until the DOM is loaded. When you run it in the <head> tag, it is running BEFORE the DOM has loaded and thus the page is empty at that point so your code can't find the proper elements to install click handlers. There are a couple ways to solve this issue. The simplest is to move all your script tags to right before </body>. This will ensure that the DOM is available when the scripts run and you won't have to do anything else special.
Here's a revision of your HTML that should work:
<html>
<head>
</head>
<body>
<div id="box" style="width: 200px; height: 100px; background: #000;">
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="script.js" type="text/javascript"></script>
</body>
</html>
You could also just switch the order of your two scripts and leave them in the <head> tag and then change your script to this:
$(document).ready(function() {
$('#box').click(function() {
alert('test');
})
});
In jQuery, the $(document).ready(fn) construct instructs jQuery to call a specific function only when the DOM has finished loading. This allows you to place this initialization script anywhere and jQuery will make sure that your callback function is not called until the DOM is ready.
When using procedural style the code seemed to be executing with the wrong width dimensions of an element (i suspect the code was executing before the element was finished being created), when i refreshed the page all was fine.
Issue:
<html>
<head></head>
<body>
<div id="parent">
</div>
<script language="javascript" type="text/javascript">
create_object(); // Creates an element and puts it inside div parent
</script>
</body>
</html>
Solution:
<html>
<head>
<script language="javascript" type="text/javascript">
window.onload = function(){
create_object(); // Creates an element and puts it inside div parent
}
</script>
</head>
<body>
<div id="parent">
</div>
</body>
</html>
What is the difference?
The window.onload waits for the page to load of course but since the is after the element.. shouldn't that be just fine?
No other java script is being executed on the page.
window.onload waits for all page resources (such as images and style sheets) to be loaded before calling its callback. In your first example, the DOM elements will all exist (because your code is executing at the end of the body after things before it have been parsed), but external resources like images may not yet be loaded and thus final layout may not yet be achieved so everything may not yet have its final size/layout.
window.onload is executed when DOM tree is ready and all resources are loaded (image, script, stylesheet ...). If you load your script in body without this callback, your div width can be wrong if you load image or stylesheet into this bloc ...