Closed Bug 72058 Opened 24 years ago Closed 23 years ago

nodeList.length not live while during document load

Categories

(Core :: DOM: Core & HTML, defect)

defect
Not set
major

Tracking

()

RESOLVED WORKSFORME
Future

People

(Reporter: georg.maass, Assigned: jst)

Details

(Keywords: hang)

This sample makes Mozilla 0.8 on WinNT to hang with 100% CPU usage. It does not display anything. If you comment out the last script line, then it does not hang. <html><head><title>Node test</title> </head> <body> <p id="p1"><b id="b1"><a id="a1">Text</a></b> <script> document.write(document.childNodes.length+'<br>'); for(i=0;i<document.childNodes.length;i++)document.write(document.childNodes[i].nodeName+'<br>'); p = document.getElementById('p1'); document.write(p.childNodes.length+'<br>'); for(i=0;i<p.childNodes.length;i++)p.childNodes[i].nodeName+'<br>'; document.write('hang in next loop!<br>'); // Browser hangs in next line for(i=0;i<p.childNodes.length;i++)document.write(p.childNodes[i].nodeName+'<br>'); </script> </body></html>
This hangs mozilla because you're creating an infinite loop, you loop over the childnodes in |p| and every iteration you add children to |p| so you'll never get to the end of the loop. The short term fix is to "don't do that then", i.e. cache the value of |p.childNodes.length| in a local variable before you do the for loop and things will not loop infinitely. There's probably something that could be done in mozilla to prevent this infinte loop, but for now it'll haveto be like it is.
Severity: critical → major
OS: Windows NT → All
Hardware: PC → All
Target Milestone: --- → Future
hang keyword, marking NEW.
Status: UNCONFIRMED → NEW
Ever confirmed: true
Keywords: hang
I think I've run into the same problem, and I don't think it's an infinite loop. <html> <head></head> <body> <script type="text/javascript"> var all = document.getElementByTagName('*'); i = 0; while (i < all.length) { document.write(i + '<br />'); i++ } </script> <a href="#" onClick="alert(all.length);return false">Click me</a> </body> </html> Change the above to: document.write(all[i].type + '<br />'); and Moz hangs and eventually stops responding. If it were an infinite loop problem, the first example would hang, or would simply write numbers forever and ever amen. The hang doesn't happen until you try to access properties of an element of the "dynamic collection" from within the script (all[i].type) coupled with adding a new element to the array (<br />). I'm using build 20010113.
This is an infinite loop, the reason: while (i < all.length) { document.write(i + '<br />'); i++ } works, and: while (i < all.length) { dump(i + ", " + all.length + "\n"); document.write(all[i].type + '<br />'); i++ } doesn't is that accessing the length of a nodelist doesn't flush the sink so you don't trigger the infinte loop. The correct behavior in this case is really the infinite loop, believe it or not. Making the testcase look like this would fix the infinite loop in all cases: var len = all.length; while (i < len) { dump(i + ", " + all.length + "\n"); document.write(all[i].type + '<br />'); i++ } node lists are live, they should always represent exactly what's in the document.
Sorry for continuing this, but I want to make sure I understand. So all.length doesn't update until you either finish running the script or until you explicitly access an object in the node list. Doesn't that mean that the first case that didn't hang is technically a bug *because* it didn't go into an infinite loop? Or am I reading too much into it? Also, on another note, if node lists are live and represent what's currently in the document, shouldn't the <SCRIPT> object be destroyed after the page is fully loaded?
The unexpected hanging, which I thought to be a bug, was result of an HTML-error in my code, as correctly detected by Johnny Stenback. I just didn't look enough to my source to detect my own error. Sorry for confusing you folks.
Justin, yes, the first testcase should've hang, it's a bug that it doesn't. :-) What do you mean by "if node lists are live and represent what's currently in the document, shouldn't the <SCRIPT> object be destroyed after the page is fully loaded?"?
Status: NEW → ASSIGNED
Summary: Mozilla 0.8 hangs with 100% CPU on document.write of nodeName → nodeList.length not live while during document load
Sorry. I very asn't clear. Well, the following code in the BODY of a page: <script type="text/javascript"> var all = document.getElementByTagName('*'); i = 0; while (i < all.length) { document.write(i + '<br />'); i++ } </script> runs when the page is loading, correct? After the page is fully loaded, you'd think that the <SCRIPT> tag no longer exists because it's done it's job. It's a run-once and forget type thing. But when I put a link in the page that cycled through the all array, I found that the <SCRIPT> is still considered a valid node. I wouldn't think it should be, but that's me. This isn't really part of this bug, but I don't know where to start trying to figure out if it's a bug of it's own or not. I'm not even sure what keywords I'd use to search bugzilla. :-)
Inline <script> tags (i.e <script>var foo=1;</script>) are executed only once (when the HTML parser sees them) but they do remain in the document until the document goes away (or until someone manually removes them through the DOM), this is not a bug, this is how it should work. From a pure DOM and HTML point of view the scipt tag is just like any other tag.
The script tag HTMLElement node must not go lost without removeChild of the parentNode. In some cases this HTMLElement is needed for later use: i.e. if I set or change it's src-Attribute to load any JavaScript features of a site on demand instead of preloading dozends of never used JavaScript libraries. In this case I need it as a container for on demand the requested library replacing the no longer requires source of the old script without loosing the JavaScript objects like functions and variables created by the old content of the node. With IE theis works fine, with Mozilla it doesn't. Assignments to the src-Attribut do not load the script. But this is an other bug. i.e. if I want to fetch the source to present it to the guest in a tutorial, I like to directly access the script tag HTMLElement node instead of typing the source twice. You see it is usefull not to loose the script tag HTMLElement node after parsing, because you can use it for usefull things. If you don't need it, you can remove it your self with the removeChild method of the parent node. Do this, if you don't like people looking into your source using innerHTML an the DOM methods. (Remember to prevent caching, if you try to protect your source)
QA Contact -> desale
QA Contact: janc → desale
Updating QA contact to Shivakiran Tummala.
QA Contact: desale → stummala
<html><head> <title>Infinite loop bug</title> <body> <script type="text/javascript"> var all = document.getElementsByTagName('*'); x = all.length; alert (all.length); //alerts 5 document.write( '<br>'); alert (all.length); //alerts 6 alert (x); //alerts 5 </script> </body> </html> looks to me like an expected behaviour, is this still valid bug. IE also does the same.
marking worksforme. The first testcase from comment 3 now hangs as well (correctly).
Status: ASSIGNED → RESOLVED
Closed: 23 years ago
Resolution: --- → WORKSFORME
Component: DOM → DOM: Core & HTML
You need to log in before you can comment on or make changes to this bug.