HTML Page life cycle JS execution order, with document ready execution - javascript

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
abc
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="Scripts/first.js"></script>
<script src="Scripts/second.js"></script>
</body>
</html>
//first.js
$(document).ready(function () {
alert(first.firstChild.firstGrandChild);
})
//second.js
var first = {
firstChild: {
firstGrandChild: false
}
}
I have simplified the problem here. We have html page that has reference to two js-first and second. So i assume browser would render html first, stop to download first js, then download second js.
Then document ready of first js would be executed which will get first.firstChild.firstChildChild of second js.
I have few questions:
What would be execution order of html execution, download js, document ready execution of fist js, document ready execution of second js (if it has doc ready)?
Now i am able to access these objects from first js but in very similar scenario in my production app, i get these as undefined sporadically. What could be possible reason for that?
If i have circular dependency b/w first and second js and i want things to functions smoothly, what should i do? (example fist js calling second js methods from document ready and from outsid doc ready too AND vice-versa)

Related

Running a js function in html while the script tag has a defer attribute set

I the defer attribute of the script tag in the <head> section of HTML files. This almost always means that I cannot run js functions in the HTML since the js file is only loaded after the HTML file has been loaded..
I have run into a situation where I needed to run a js function in my HTML file, but would not want to remove the defer attribute from the script tag because of other functions in the js file. I looked at the possibility of using async, but it also was not helpful.
Any idea on how this could be done... other than using defer? I would still like to keep the script tag in the head, but going that way would mean that I have no open (non-function based) instructions in the linked js file... which is not always ideal.
Here is a sample of the HTML file
temp.html
<!DOCTYPE html>
<html lang="en">
<head>
<script src="temp.js" defer></script>
<title>Defer et al</title>
</head>
<body>
<script>
runThisFunction('Home');
</script>
</body>
</html>
And here is a sample of the js file
temp.js
function runThisFunction(varin) {
console.log(varin);
}
If I remove the defer from the js file, the function will run; if I leave it there, or use async instead, the function will not run because it has not loaded yet.
Any assistance in this small issue will be appreciated.
The best way to do this would be to refactor your script to contain an entry point in a function, and run that function once the DOM loads. Instead of, for example
// temp.js
function runThisFunction(varin) {
console.log(varin);
}
document.querySelector('.foo').textContent = 'doing stuff';
// other code here
put all of the functionality that depends on the page being loaded into its own function:
// temp.js
function runThisFunction(varin) {
console.log(varin);
}
function init() {
document.querySelector('.foo').textContent = 'doing stuff';
// other code here
}
window.addEventListener('DOMContentLoaded', init);
This way, if you also remove the defer attribute, runThisFunction will be available immediately, but the other parts of your code won't run until the page is loaded.

Loading jquery in the last position

I offen heard that loading jquery as last element is a good idea because this way a web page loads faster. At the same time I have a script in the header which shows error:
$(document).ready(function () {// Uncaught ReferenceError: $ is not defined
...
}
Should I move jquery loader before the script or I need to change this script some way?
Your concrete issue stems from the fact that you execute statements that use jQuery (i.e. they execute $, which is a function in the jQuery library, also called "the jQuery function" because jQuery is an alias) before it is loaded.
True, it is typically recommended to load scripts last, but that still means the scripts have to be loaded in the correct order, with usually jQuery before your own scripts using jQuery.
If you really want to load your own scripts before jQuery for some reason, you need to defer its execution and have a third helper script to run it, e.g.:
// script.js
(function() {
function myLibraryMainFn() {
$('div').text('simulating work, utilizing jQuery');
}
window.myNamespace = {
run: function() {
myLibraryMainFn()
}
};
}());
<!DOCTYPE html>
<html>
<body>
<div></div>
<script src="script.js"></script>
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script>
// Run your script now:
window.myNamespace.run();
</script>
</body>
</html>
Always refer library file first(in your case jQuery), then use it next..For page load and performance add it before body end tags of your HTML

External JS sometimes doesnt loads in time?

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="a.js"></script>
</head>
<body>
<script>
functionFromAJS();
</script>
</body>
</html>
this works OK most of the time, but on production server, its not 100%. It says that functionFromAJS() doesnt exists, which is ok, if the .js is not gets loaded in time. But then what to do?
EDIT: Using the window.onload function should not do any difference as long as the script you're embedding is loaded before the function call. Then the a.js file will be loaded before <script>functionFromAJS();</script> anyway and you should be able to execute the function if it exists.
Try using:
<script>
window.onload = function() {
functionFromAJS();
};
</script>
So that the function is not called before the document is fully loaded.
Or if you're using jQuery you can use:
<script>
$(document).ready(function() {
functionFromAJS();
});
</script>
If the function doesn't exist, then it's not a matter of the file not being loaded in time, then the file isn't loaded at all.
When the browser encounters a script tag for loading a file, then it will stop the parsing of the page until the file has been loaded, or until the file fails to load. The functionFromAJS will never be called before the browser has completed the attempt to load the file.
If the file fails to load, then there isn't much you can do. You can check if the function exists before you call it to avoid the error. You could even try to load the script again, but if it failed the first time then it's likely that it will still fail.

Best way to fire events when single elements in the document becomes ready

I'm developing a web application that because of performance concerns is heavily reliant on Ajax functionality. I'm attempting to make parts of each page available while longer running modules load.
The issue is that I want to kick off the Ajax requests as soon as possible (in the head of the document). This part works fine; the issue is on rare occasion, the Ajax call will come back before the area that I want to load the Ajax data into is present on the page. This causes the data to not be loaded.
To get around the issue I started using script tags below each of my containers that resolve a JQuery promise to let the code know that the area is available.
EDIT: I want to load the data into the area as soon as it becomes available (before full document load).
The current pseudo code looks like this:
<head>
<script>
var areaAvailablePromise = new $.Deferred();
$.when(areaAvailablePromise, myAjaxFunction()).then(function(){
// load data into the element.
});
</script>
</head>
<!-- much later in the document -->
<div class="divIWantToLoadAjaxContentInto"></div>
<script>
areaAvailablePromise.resolve();
</script>
My question is: is there ANY better way to handle this situation? Every one knows that inline scripts are blocking and are bad for performance. Also, I feel that this is going to lead to cluttered code with micro-script tags all over the place.
Put your (whole) <script> tag just after the element.
HTML is parsed from top to bottom, so the element will be loaded already.
No. There really is no better way to my knowledge.
<!doctype html>
<html>
<head>
<script src="jquery.min.js"></script>
<script src="q.min.js"></script>
<script>
var elD = Q.defer();
var dataP = Q($.ajax(…));
Q.spread([elD.promise, dataP], function (el, data) {
…
}).done();
</script>
</head>
<body>
…
<div id="foo"></div>
<script>elD.resolve($("#foo"));</script>
…
</body>
</html>
you can use:
$(document).ready( handler )
(recommended)and also has contracted form:
$(handler)
exemple:
$(function(){
alert("OK");
})
read more: http://api.jquery.com/ready/

javascript function call not working

Inside register.js I have a function called username() and I want to call it from my webpage but the function will not run.
Here is where I include the .js file and call the function:
<head>
<link rel="stylesheet" href="css/base.css" />
<script src="resources/jquery-1.8.1.min.js"></script>
<script src="resources/register.js"></script>
<script type="text/javascript">username();</script>
</head>
This is in the .js file:
function username(){
document.getElementById("username").innerHTML="Username already in use";
}
This is a common mistake from folks just starting out in Javascript. Trouble is, if you don't know what to call it, it is hard to search for the answer.
What is happening: When the <head> element is processed, nothing in the document body exists yet. Your element username doesn't exist, so the getElementById fails.
Solution 1 Move <script type="text/javascript">username();</script> to just before the </body> so everything will be in place.
Solution 2 Use the onload event to run your Javscript after everything else runs with a
<body onload="username()">
(jQuery has its own onload event handling as well.)
You have no element with the id username.
(You might have one lower down in the document, which you haven't shared with us, but since you are calling the function directly (and not in response to an event, such as load) while still in the <head> it won't yet exist.)

Categories