how to check DOM is ready using JavaScript? - javascript

i am using this script in my jsp. some time when i click on that particular button it works fine but some time it doesn't work and show Script Error : document.form is null not an object. what ever i searched i found that document is not finished loading when i call reset. how can i check whether the document has loaded or not?
<head>
<script type="text/javascript">
function closeWarning(){
document.forms[0].reset();
}
</script>
</head>
<body onLoad="closeWarning();"
<jsp:include flush="true" page="/myCart/header.jsp"/>
<div>
// content of body
</div>
</body>

If you don't want to use jQuery, you can use an event listener for DOMContentLoaded, as in:
if(document.addEventListener) document.addEventListener("DOMContentLoaded",closeWarning,false);
This will work for everyone except IE, which uses onreadystatechanged, as in:
document.onreadystatechange=function() { if(this.readyState=="complete") { closeWarning();
}
}

One way is using jQuery and it's ready() function.

Related

Does jQuery .length defies DOM ready?

I have this code:
Function loader() will keep running until <body> does exist. When <body> does exist, insert .loader
<html>
<head>
<script type="text/javascript" src="jquery/jquery-3.2.1.min.js"></script>
<script type="text/javascript">
loader();
function loader() {
if (!$('body').length) {
window.requestAnimationFrame(loader);
} else {
$('<div class="loader"></div>').prependTo('body');
}
};
</script>
</head>
<body>
<!-- elements -->
</body>
</html>
I want to ask this line
if (!$('body').length) {}
What do .length use to determine its return, is it <body> or <body></body>? Does .length wait for closing tag </body> or not? If it does, what is my alternatives? I need .loader to be inserted without waiting for </body>.
My last resort would be
<body>
<div class="container"></div>
<!-- rest of elements -->
</body>
So then
if (!$('.container').length) {}
But I need alternatives that don't interfere with the elements structure.
EDIT:
I rephrase the question and add below codes.
<html>
<head>
<script type="text/javascript" src="jquery/jquery-3.2.1.min.js"></script>
<script type="text/javascript">
$(function(){
console.log("ready timestamp");
});
loader();
function loader() {
if (!$('body').length) {
window.requestAnimationFrame(loader);
} else {
console.log("length timestamp");
}
};
</script>
</head>
<body>
<!-- elements -->
</body>
</html>
Output:
15:03:19.862 length timestamp
15:03:20.198 ready timestamp
Length timestamp always lower than ready timestamp.
Tested with:
Chrome 71.0 and FF 65.0
Enable timestamp in Console Settings (Developer Tools -> Console -> Show timestamps).
Other might ask why I did this, what's right about 300ms?
I implement PWA and need loader, like this:
Showing loader while navigating between pages - PWA.
The problem is, there is 300ms between .on('beforeunload') of the previous page and $() of the next page. It's a blip, obviously.
This blip can ideally/easily be solved by server side scripting but as I mentioned above, I have no access to server side scripting, the furthest I can ask is a blank element <div class="container"></div>.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
console.log( $('#tryToFindMe').length );
</script>
<div id="tryToFindMe"></div>
Similar to how your question tries to access the body before it is defined, this snippet tries to access the div before it is defined. In both cases, the element will not be found.
The reason for this is because when your browser is parsing your webpage into the Document Object Model it parses from top down. So at the point that the script runs, the html that will create the div in the DOM has not been processed yet. So the script tries to lookup the element, it does not exist, and the length is zero.
This is why using the jQuery document ready, binding to the DOMContentLoaded event or the load event exist. These different approaches defer the execution of your logic until either the entire page has been parsed into the DOM, or in the case of load, that not only the page has been parsed into the DOM, but all the resources have been received as well (images, videos, etc). Without these approaches, the script will need to appear in the page after the element is defined to ensure the element exists already in the DOM.
The important part when thinking about interacting with the DOM is not to think in terms of HTML. The DOM contains Nodes, not HTML. The nodes are generated from the HTML.
You can just use a jQuery document ready function ($(() => {})) like so:
$(() => {
$(`<div class="loader"></div>`).prependTo("body");
});
I ran another test.
<html>
<head>
<script type="text/javascript" src="jquery/jquery-3.2.1.min.js"></script>
<script type="text/javascript">
$(function(){
console.log("ready timestamp");
});
loader_bottom();
loader_body();
loader_top();
function loader_bottom() {
if (!$('.container_bottom').length) {
window.requestAnimationFrame(loader_bottom);
} else {
console.log("container_bottom.length timestamp");
}
};
function loader_top() {
if (!$('.container_top').length) {
window.requestAnimationFrame(loader_top);
} else {
console.log("container_top.length timestamp");
}
};
function loader_body() {
if (!$('body').length) {
window.requestAnimationFrame(loader_body);
} else {
console.log("body.length timestamp");
}
};
</script>
</head>
<body>
<div class="container_top"></div>
<!-- elements between -->
<div class="container_bottom"></div>
</body>
</html>
Output:
09:09:16.894 body.length timestamp
09:09:16.897 container_top.length timestamp
09:09:17.090 container_bottom.length timestamp
09:09:17.220 ready timestamp
Because $('.container_top') adjacent to $('body'), changing the sequence,
loader_top();
loader_body();
Not suprisingly output:
09:09:39.708 container_top.length timestamp
09:09:39.708 body.length timestamp
Hence I come into conclusions:
Does jQuery .length defies DOM ready? Yes it does.
What do .length use to determine its return, is it <body> or <body></body>? It is <body>.
Although the right phrase for second question should be:
What DOM Parser use to determine nodes, is it <tag> or <tag></tag>? The answer is <tag>.
Actually I'm not surprised that we can manipulate DOM before it's ready. Besides, $().ready() is just an event when DOM is ready. Javascript is multi-thread so (I thought) DOM Manipulating should could run parallel with DOM Parsing. Not until this code I can prove that.

focus() won't work - query

I have some input field, and I call this in my js file
$(document).ready(function () {$('#input_id').focus(); });
but it doesn't launch. Even, when I launch it in my chrome console, I get no focus. How can it be
This is working sample for a text input, just match with your page code and see what you are missing as compared to this.
I assume that you have referred jquery js already and any other jquery functions work well in your page.
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js">
</script>
<script>
$(document).ready(function ()
{
$('#input_id').focus();
});
</script>
</head>
<body>
<input type="text" id="input_id"/>
</body>
</html>
In any case please make sure that there is no js error in your page as
$('#input_id').focus(); must work fine individually, so only thing looks wrong could be reference to jquery, else some js error before code reaches to .focus() call on input_id.
Also you can validate if on your page focus for the input working fine, for this keep $('#input_id').focus(); in a script tag just before your body page ends/closes,
to make sure input control, jquery reference are placed correctly and page has no js errors, if this way too focus doesn't work then something is wrong with any of these 3.

where to embed javascript section in a html page [duplicate]

This question already has answers here:
when and where to put javascript in html
(7 answers)
Closed 9 years ago.
the thing is i'm unable to figure out where to embed javascript in html page whether in head section or body section.
example 1:
<html>
<head>
<title>events</title>
<script>
document.getElementById("b").onclick=function(){displayDate()};
function displayDate()
{
document.getElementById("demo").innerHTML=Date();
}
</script>
</head>
<body>
<p id="demo"></p>
<button id="b">new</button>
</body>
</html>
in the above example I placed script tags in head section but it is not working.
example: 2
<html>
<head>
<title>events</title>
<script>
function upper()
{
var x=document.getElementById("t");
x.value=x.value.toUpperCase();
}
</script>
</head>
<body >
enter some text:<input type="text" id="t" onChange="upper()"/>
</body>
</html>
in the second example I placed the javascript in head section it is working properly.first example demonstrates that on clicking a button date will be displayed in the second example in a text box when data is entered and if we come out of the box the letters in the box will we converted to uppercase.
To have it more readable I prefer to always place JavaScript in the head section. If you need to access elements from there, use the window.onload event:
<head>
<title>events</title>
<script type="text/javascript">
window.onload = function() {
document.getElementById("b").onclick = function() {
displayDate();
};
};
function displayDate()
{
document.getElementById("demo").innerHTML=Date();
}
</script>
</head>
This would work just fine.
Your second example worked because you just defined a function, you didn't try to access any element.
You can put it in the head. The problem is that your examples are not the same. The first one doesn't work because the current date is retrieved by calling Date(), when it should be new Data().getDate(). The second example works because the code is valid.
The problem you're running into is that you're trying to reference an element before it is loaded into the DOM.
When you're putting the script in the HEAD tag, the dom hasn't been loaded yet and the document.getElementById won't find what you're looking for.
You have a few different options to deal with this. You can put the script at the end of the page, which will work for your small example here.
Probably a better option is to take a look at learning/using jquery or another js utility. Jquery makes it easy to solve this issue by giving you a "ready" event. This ready event will be triggered when the DOM is fully loaded. So:
$(document).ready(
function()
{
$("#demo").html((new Date()).toString());
});
Is all you really need. With this approach, it doesn't matter where the script it on the page.

Basic jQuery .load Problem

I am trying to use jQuery's .load function to dynamically load content into my webpage. This seem so simple, but I cannot make it work. To try and figure it out, I made a test page with just basic structure, but the external content still won't load:
jquery.html
<html>
<head>
<title>JQuery Test</title>
<script src="jquery1.5.min.js"></script>
</head>
<body>
<script>
$('#foo').load('test.html');
</script>
<div id="foo"></div>
</body>
</html>
test.html
<p>Text text</p>
I'm sure I have made a tiny error, but I can't find it anywhere!
You need to encapsulate your script in the $(document).ready() otherwise #foo won't exist when the script is executed:
<script>
$(document).ready(function(){
$('#foo').load('test.html');
});
</script>
You need to wait for the document to be ready before you can access the DOM. Just add a $(document).ready() around your original code:
<html>
<head>
<title>JQuery Test</title>
<script src="jquery1.5.min.js"></script>
</head>
<body>
<script>
$(document).ready( function() {
$('#foo').load('test.html');
});
</script>
<div id="foo"></div>
</body>
</html>
or if you want a shorter code:
$(function() {
$('#foo').load('test.html');
});
Informally, what's happening is that, as your browser reads the code you wrote, it's drawing its contents as it goes along. When it reaches your <script> tag, it executes it. But when $("#foo") gets executed, the browser's still processing the <script> and hasn't reached the part of the code where you told it there's a div called foo, so the browser doesn't know it exists, and jquery will just find nothing.
Of course, the idea that the browser will just sequentially read your code and render it as it goes is naive at best, so while it might seem that just moving the <script> tag to the bottom of the code would work, you're not actually guaranteed it will work. Instead, the browser will notify you when it's done drawing the page by firing a load (and possibly a DOMContentLoaded) event. So all code that depends on the whole html being drawn should be executed in an event handler bound to those events.
jQuery makes waiting for the page to be loaded easy, just use something like this:
$.ready(function() {
doStuff();
});

JavaScript: trouble assigning event handlers

I'm not sure what I'm doing wrong here:
index.html
<?xml version="1.0" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "XHTML1-s.dtd" >
<html xmlns="http://www.w3.org/TR/1999/REC-html-in-xml" xml:lang="en" lang="en" >
<head>
<script type="text/javascript" src="scripts/eventInit.js"></script>
</head>
<body>
<p id="javascriptWarning">This page will not work with JavaScript disabled.</p>
</body>
</html>
eventInit.js
window.onload = function () {
alert("check"); // works
var jsWarning = document.getElementById("javascriptWarning");
jsWarning.onclick = function () {
alert("hi"); // works
};
jsWarning.onload = function () {
alert("loaded"); // fails
};
}
And yet, nothing happens. What am I doing wrong? I've tried other events, like onmouseover and onload.
I'm doing this in Visual Studio, and intellisense isn't giving me options for setting any event handlers. Is that because I'm doing this wrong?
I have confirmed that JS is working on my setup; just putting alert("hi") in a script and including it does work.
It might be important to note that I'm doing this in JScript, since I'm using Visual Studio 2010, so perhaps event handling is different?
Updated to remove '-' from the ID name, but it still doesn't work.
Updated added the window.onload block. Now onclick works, but onload doesn't.
You are trying to set a load event on a paragraph. Only objects which load external data (window, frame, iframe, img, script, etc) have a load event.
Some JS libraries implement an available event (such as YUI) — but you know the paragraph is available, since you're setting an event on it, and you couldn't do that if it was unavailable.
maybe you forgot to have the code block inside a
window.onload = function() {
// btn click code here
}
You have to wait for the document to be parsed before you can go looking for elements by "id" value. Put your event handling setup into an "onload" function on the window object.
The browser won't fire an "onload" event on your <p> tag. You won't need that anyway if you do your work in the "onload" handler for the window as a whole.
[soapbox] Use a framework.
The script is executed before the desired element exists. Additionally, I don't think, p has an onload-Event. Windows, frames and images, yes, but paragraphs?
You should use <body onload="init();"> or window.onload=function(){ … } or a library function, if you use a library. Example:
index.html
<?xml version="1.0" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "XHTML1-s.dtd" >
<html xmlns="http://www.w3.org/TR/1999/REC-html-in-xml" xml:lang="en" lang="en" >
<head>
<script type="text/javascript" src="scripts/eventInit.js"></script>
</head>
<body>
<p id="javascriptWarning">This page will not work with JavaScript disabled.</p>
</body>
</html>
scripts/eventInit.js
window.onload=function(){
alert('JS is working!');}
Edit: Okay, I am very sure, p makes no use of an onload event handler. And it's no wonder, you don't need it. If you want to execute JS code just after the paragraph is finished, do this:
<p>
<!-- stuff -->
</p>
<script type="text/javascript">
/* stuff */
</script>
Instead of this:
jsWarning.onload = function () {
alert("loaded"); // fails
};
try this
if(jsWarning) alert("loaded");
I think someone above mentioned checking for the existence of the element. At this stage the element should be present but it does no harms to check for it.
I think you have to make sure your JavaScript is binding.
Is your javascript before or after your paragraph element, for some reason my brain is aiming towards that.
I would look into using something like jQuery, it will help.
using jQuery your code would be (with the relevant jQuery files included of course):
$(document).ready(function()
{
$("#javascript-warning").click(function(){
alert("HELLO");
});
});
I don't think hyphens are valid in class names when used in conjunction with JavaScript. Try an underscore instead.
onload is a window event.

Categories