I was reading w3schools and found this example:
<body>
<p>Hello World!</p>
<p>The DOM is very useful!</p>
<p>This example demonstrates the <b>length</b> property.</p>
<script type="text/javascript">
x=document.getElementsByTagName("p");
document.write("------<br />");
for (i=0;i<x.length;i++)
{
document.write(x[i].innerHTML);
document.write("<br />");
}
document.write("------");
</script>
</body>
which works just fine. Then I thought doing the same with jQuery with
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Demo Page</title>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="code.js"></script>
</head>
and then in the code.js file have
$(document).ready(function() {
x=document.getElementsByTagName("p");
document.write("------<br />");
for (i=0;i<x.length;i++)
{
document.write(x[i].innerHTML);
document.write("<br />");
}
document.write("------");
});
But with the second example, using jQuery the page loads forever
and never prints the p
tags innerHTML values.
Why is this?
I was reading w3schools and found this example:
<body>
<p>Hello World!</p>
<p>The DOM is very useful!</p>
<p>This example demonstrates the <b>length</b> property.</p>
<script type="text/javascript">
x=document.getElementsByTagName("p");
document.write("------<br />");
for (i=0;i<x.length;i++)
{
document.write(x[i].innerHTML);
document.write("<br />");
}
document.write("------");
</script>
</body>
which works just fine. Then I thought doing the same with jQuery with
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Demo Page</title>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="code.js"></script>
</head>
and then in the code.js file have
$(document).ready(function() {
x=document.getElementsByTagName("p");
document.write("------<br />");
for (i=0;i<x.length;i++)
{
document.write(x[i].innerHTML);
document.write("<br />");
}
document.write("------");
});
But with the second example, using jQuery the page loads forever
and never prints the p
tags innerHTML values.
Why is this?
Share Improve this question edited Jun 4, 2011 at 22:53 orftz 1,14813 silver badges22 bronze badges asked Jun 4, 2011 at 22:40 Dora G.Dora G. 131 silver badge3 bronze badges 4- 5 This is because your using W3Schools to learn from. W3Schools is a bad reference and full of broken code. Learn from the MDN – Raynos Commented Jun 4, 2011 at 22:43
- Thank you for the reference... but stil why isnt the above code working? – Dora G. Commented Jun 4, 2011 at 22:45
- 5 As a follow-up on what Raynos said, I'll provide this link since you'll eventually run into it anyway if you keep learning from w3schools: w3fools. – Joris Ooms Commented Jun 4, 2011 at 22:45
-
2
Using
document.getElementsByTagName
with jQuery... brilliant.</sarcasm>
– Matt Ball Commented Jun 4, 2011 at 22:46
4 Answers
Reset to default 3calls to document.write
after document.ready rewrites the document. and single the return value of document.getElementsByTagName
is a live list the list bees empty.
So what actually happens is that the document contains.
<p>Hello World!</p>
<p>The DOM is very useful!</p>
<p>This example demonstrates the <b>length</b> property.</p>
When the document is ready you call x = document.getElementsByTagName("p");
and x
contains an array of <p>
elements. But this is a live list and reflects the live state of the document. So when <p>
elements get removed the list gets updated automatically.
You then call document.write
with "-----<br/>"
and this empties the document and replaces it with that. So the variable x
now contains 0 <p>
elements becuase there are 0 in the document.
The for loop doesn't run because x.length === 0
As mentioned this is broken because W3Schools gives you broken code.
I highly remend you learn from the MDN
Live Example
A better way to achieve this with jQuery would be :
$(document).ready(function() {
var ps = $("p");
var body = $(document.body);
body.append("------" + "<br/">);
ps.each(function() {
body.append(this.innerHTML + "<br/>");
}):
body.append("------");
});
Live Example
Don't use document.write
after the DOM is loaded, as it is with jQuery's $(document).ready
. In fact, don't use document.write
with jQuery at all. Use DOM manipulation instead. For instance:
$(document).ready(function() {
var x = $('p'),
toAdd = '';
x.each(function() {
toAdd += this.innerHTML;
});
$(document.body).append(toAdd);
});
See $
, each
, append
.
Basically, learn jQuery's paradigms and patterns, and use them. Don't expect to be able to drop jQuery syntax randomly into Javascript code. Moreover, don't listen to W3Schools.
You should read about document.write
from a proper resource:
Writing to a document that has already loaded without calling
document.open()
will automatically perform adocument.open
call. Once you have finished writing, it is remended to call document.close(), to tell the browser to finish loading the page.
As you are running the jQuery code on the document.ready
event, the document (the structure) is already loaded. That means document.open
is called. Lets see what MDC says about it:
If a document exists in the target, this method clears it (see the example above).
That means all the existing content is removed. Hence your code cannot access the p
elements as they don't exist anymore.
Why does it work without jQuery?
In the original code, the JavaScript is executed before the structure finished loading (as it is part of it itself). Therefore document.open
is not called and the content is not cleared:
If the
document.write()
call is embedded directly in the HTML code, then it will not calldocument.open()
.
There is hardly ever a reason to use document.write
. Use proper DOM manipulation methods instead if you want to modify the document. You can find a list of methods provided by jQuery here.
that's because every time jQuery writes in the document you made some new elements so all scripts in the $(document).ready(); should be done again another time
maybe the solution is to write in another element like a "div"
$(document).ready(function() {
x=document.getElementsByTagName("p");
$('div.myDiv').html("------<br/>");
for (var i=0; i<x.length; i++)
{
$('div.myDiv').html(x[i].innerHTML());
$('div.myDiv').html("<br />");
}
$('div.myDiv').html("------");
});
in the body you should put a "div" with a class name like "myDiv"