In all the research I've done, I am under the impression function calls in 'scr' files is not executed until called in the of the DOM. But this does not seem to be true.
My example:
<title id="pageTitle">Investment(s)
</title>
<script type="text/javascript" src="../javascript/library.js">
</script>
<script type="text/javascript" src="../javascript/investment.js">
</script>
...any function in either 'src' file with an alert() statement, shows up at onLoad(). Is this normal?
Thanks for any help you can offer.
<script> tags cause the browser to stop what it is doing and begin downloading/executing the script immediately. They do not wait for the dom to finish loading before they run. Read more.
Related
It is well known to everyone that using defer is an efficient way to minimize the loading time of a website.
In my project, I am using Vue (included in the header using defer) and in a circumstance, I want to use a component that is created by another person. When I try to do Vue.Component(...) in the body of the HTML, it says Vue is undefined. It seems that my script in the body is running before the external script has been loaded. Is there any way to fix this issue?
I tried to do document.onload, but the function itself is not working.
PS: Just to be clear, the external script is referring to my js file where Vue is defined and I am not talking about the third party library at all.
Instead of document.onload you need to use window.onload or document.body.onload.
But an even better way is to wait for the load event on <script> tag:
<html>
<head>
<script id="vue-script" src="vue.js" charset="utf-8" defer></script>
</head>
<body>
<script type="text/javascript">
function onVueLoaded() {
Vue.render();
}
if ('Vue' in window) {
onVueLoaded();
} else {
var script = document.getElementById('vue-script');
script.addEventListener('load', onVueLoaded);
script.addEventListener('error', () => console.warn('failed to load Vue.js'));
}
</script>
</body>
</html>
Here I also added a handler for the error event if you wanted to explicitly handle loading errors.
Tell me if I am wrong. The JavaScript code execute as a single thread.
The execution of below JavaScript code will be A,B and C, sequentially right.
<script src="A"> .... </script>
<script src="B"> .... </script>
<script src="C"> .... </script>
The execution of below code will depend upon the code and the time given to each scripts means first 'A' will start to execute (or 'B', don't know), the execution of 'A' will stop because the time given to it is complete than the others will get the same chance say 'B' , than 'C' and than 'A' again resume and the cycle goes on till the execution of each scripts done.
<script async src="A"> .... </script>
<script async src="B"> .... </script>
<script async src="C"> .... </script>
But what happen when there are both synchronous and asynchronous scripts occur like below.
<script sync src="A"> .... </script>
<script async src="B"> .... </script>
<script sync src="C"> .... </script>
<script sync src="D"> .... </script>
<script async src="E"> .... </script>
The async attribute merely means that the script will be downloaded sometime later and therefore will start executing sometime later. <script> tags without that attribute will be downloaded immediately and block the rest of the page until the download and execution is finished.
async does not mean that once the script runs, it may get interrupted at any time and another script may start to run. That is cooperative multitasking/CPU scheduling and is absolutely not what happens here. The first async script which happens to complete downloading will run, until it is done, at which point the next script will start to run if there's any.
So, yes, with async you do not know when your script will start executing, but once it does, it is the only thing running until it relinquishes that power (meaning the script and/or function exits).
I haven't seen anywhere the sync attribute that we can use. As far as I know there's only the way we can use the attribute is async.
But for your query, you should be using without attribute and this will be synchronous automatically:
<script src="A"> .... </script>
<script async src="B"> .... </script>
<script src="C"> .... </script>
<script src="D"> .... </script>
<script async src="E"> .... </script>
And now to answer your question,
Asynchronous scripts are loaded in the background while synchronous scripts are loaded in order and affect html and css also.
So, we can not guarantee that using like your exammple order of scripts with synchronous and asynchronous scripts because asynchronous scripts loaded in the background and may be loaded before or after the other synchronous scripts.
In the below code,
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Falback procedure</title>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js">
</script>
<script type="text/javascript">
if(typeof jQuery === 'undefined')
document.write('<script type="text/javascript" src="../localfolder/jquery.js"></script>');
</script>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/angular.js/2.0.0-beta.0/angular2.js">
</script>
</head>
<body>
<p>Hello</p>
</body>
</html>
considering a scenario, where google CDN has reach-ability issues that triggers fallback mechanism of loading local jQuery library(sitting in webserver).
In such scenario, Does angularjs library get loaded? after executing document.write
You have two problems with that code that are likely to be making it not behave as you expect:
You have a literal </script> inside a script block. It doesn't matter that it's inside a string, it terminates the block it's in. You have to break it up so the browser doesn't see it as the end of the block:
<script type="text/javascript">
if(typeof jQuery === 'undefined')
document.write('<script type="text/javascript" src="../localfolder/jquery.js"><\/script>');
// Note the \------------------------------------------------------------------^
</script>
The \ there is meaningless in JavaScript, but prevents the browser from seeing </script> and thus from ending the script block prematurely. Other ways you see it done are '....<' + '/script>' or '...</scr' + 'ipt>', etc.
Your src on the Angular script is incorrect, so it won't work whether jQuery loads or not (or from where). You've made the URL relative to the path of the page, but you need to make it at least protocol-relative by adding //:
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/angular.js/2.0.0-beta.0/angular2.js">
</script>
<!-- here --------------------------^ -->
In a comment, you asked
I was wondering, whether document.write was an asynchronous execution
No, it happens immediately when the function is run. In your case, since the function is at the top level of a script tag with no special attributes, the HTML parser has to screech to a halt and run that JavaScript code, processing any tokens the JavaScript code outputs via document.write, and waiting until the JavaScript code finishes before moving on to the Angular part.
The browser may well be able to scan ahead to preload the angular.js file, but it won't execute the contents of that file until the parser has reached that file's script tag, because the order in which scripts execute is well-defined (e.g., in document order) unless you use the async or defer attributes.
I theoretically know the differences between async and defer used in <script> tag.
async: The script is executed asynchronously with the rest of the page (the script will be executed while the page continues the parsing).
defer: The script is executed when the page has finished parsing.
But can't understand the mechanism they follow.
I have the following 2 files-1.js and 1.html.
1.js
alert('Running external JS');
1.html
<html>
<body>
<script src="1.js" async></script>
<script>
for(var i=0;i<5;i++)
{
alert('HTML code1');
}
</script>
<script>
for(var i=0;i<5;i++)
{
alert('HTML code2');
}
</script>
</body>
</html>
The html file executes s.t. all the alert statements execute first and then at last the script 1.js executes i.e. it acts similarly as when I use defer in place of async in the <script>-tag.
As per my expectation as the external script is much smaller than the code in the HTML itself it should have been triggered anywhere in between the alert statements in the HTML document as I am using async but acting similar to the effect of using defer.
Please explain what happened here also please correct me if I am wrong.
I'm learning JavaScript for a project, but I am stuck at the very beginning. I boiled it down, to the function in my script not being defined, but as near as I can tell it is defined.
I have a script: "script.js" with the function display result.
function displayResult()
{
document.write("hello world");
}
in the header of index.html I have this line
<script type="text/javascript" href="script.js"></script>
I have this line later
<body onload="displayResult()">
I have no idea why my function will not call. I would appreciate the help.
<script type="text/javascript" href="script.js"></script>
Should be:
<script type="text/javascript" src="script.js"></script>
there is no href attribute to a script block, its included from an external source through the src attribute.
BTW, calling document.write after the document has finished loading will first clear the entire content of the document, then replace it with whatever you pass to the call (in this case, 'hello world', which is not a valid HTML or XML document).