Closed Bug 296230 Opened 20 years ago Closed 19 years ago

javascript removeNode only affects the view, NOT the DOM

Categories

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

x86
Windows XP
defect
Not set
normal

Tracking

()

RESOLVED FIXED

People

(Reporter: nicolas, Assigned: peterv)

References

Details

Attachments

(3 files)

User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8b2) Gecko/20050601 Firefox/1.0+ Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8b2) Gecko/20050601 Firefox/1.0+ I'm using javascript to populate an html table using the DOM functions createElement, appendChild, etc. But there is a problem when I try to remove the rows: I first loop in the childNodes of the tbody and remove some of the rows. The result is immediately visible in the page. Then I reloop in the childNodes of the tbody to remove some other rows. Surprisingly, the rows I removed first are still there (from a javascript point of view) and if I try to remove one of those ghosts, I get the following error: Error: uncaught exception: [Exception... "Node was not found" code: "8" nsresult: "0x80530008 (NS_ERROR_DOM_NOT_FOUND_ERR)" location: "http://localhost/functions.js Line: 58"] If I go to the DOMInspector, the rows don't appear in the DOM tree, but are still shown in the childNodes of the tbody in the Javascript Object view. Here is the tree : table tbody tr td input type=checkbox (checked: the row is to be removed) td text and image tr (same as above) tr (same as above) tr (same as above) Reproducible: Always Steps to Reproduce: 1. create a new file and paste this code: <html> <head> <script type="text/javascript"> function removeFromList(tBody){ n_tbody = document.getElementById(tBody); n_trs = n_tbody.childNodes; n_toRemove = Array(); for(i_tr in n_trs){ /* skip the non-tr nodes */ if(n_trs[i_tr].nodeName==undefined || n_trs[i_tr].nodeName.toLowerCase()!="tr") continue; /* get the checkbox directly (quick and dirty, without checks) */ n_input = n_trs[i_tr].firstChild.firstChild; if(n_input.checked==true){ n_toRemove.push(n_trs[i_tr]); } } /* remove the nodes */ while(n_tr = n_toRemove.pop()) n_tbody.removeChild(n_tr); /* <-- error here */ } </script> </head> <body> <form> <table> <tbody id="foo"> <tr><td><input type="checkbox"/></td><td>cell1</td></tr> <tr><td><input type="checkbox"/></td><td>cell 1</td></tr> <tr><td><input type="checkbox"/></td><td>cell 2</td></tr> <tr><td><input type="checkbox"/></td><td>cell 3</td></tr> <tr><td><input type="checkbox"/></td><td>cell 4</td></tr> </tbody> </table> <input type="button" value="remove" onclick="removeFromList('foo')"/> </form> </body> </html> 2. Open the page with firefox, select AT LEAST TWO checkboxes and click "remove" 3. Select another checkbox and click "remove" Actual Results: The first time, the rows are removed The second time, I get a javascript error --> the DOM view shows 3 lines, the Javascript object shows 4! BUT: when only one checkbox is selected at a time, everything goes well. Expected Results: The rows should be removed, the Javascript object and dom tree sould be synchronized
Attached file test case
This is the proposed code that causes the error as a testcase. I do get an error: Error: uncaught exception: [Exception... "Node was not found" code: "8" nsresult: "0x80530008 (NS_ERROR_DOM_NOT_FOUND_ERR)" location: "file:///C:/Documents%20and%20Settings/Adam%20Guthrie/Desktop/testcase.html Line: 19"] but I'm not sure whether this has to do with just bad JavaScript of Firefox's implementation of it.
I've checked and double-checked the javascript code, but maybe I missed something. But the thing that really strikes me is that the Javascript Object (childNodes of the tbody object) does not match the DOM tree.
Attached file Reduced Testcase
The initial code does not do what the author intended since it uses the in operator with an array and thus loops through both the numeric array properties and the length and item properties. It does seem to reveal something strange though, see the testcase, try running it with the for loop commented out to see the difference in behaviour. ->Core: DOM Core
Assignee: nobody → general
Component: General → DOM: Core
Product: Firefox → Core
QA Contact: general → ian
Version: unspecified → Trunk
Depends on: 100499
Attached patch v1Splinter Review
Assignee: general → peterv
Status: UNCONFIRMED → ASSIGNED
Attachment #196017 - Flags: superreview?(jst)
Attachment #196017 - Flags: review?(jst)
Comment on attachment 196017 [details] [diff] [review] v1 Ugh, attached wrong patch, pretend |*vp = nsnull| is actually |*vp = JSVAL_NULL|
Comment on attachment 196017 [details] [diff] [review] v1 Looks good, but I'd say we should probably use JSVAL_VOID here, not JSVAL_NULL. If you today do alert(nodelist[500000]), you'll get undefined, not null (except if you're perverted enough to have that many nodes in the list, or course), so accessing an entry by an index that used to exist but doesn't exist any more, you should get back the same value as you did when the entry never did exist. r+sr=jst
Attachment #196017 - Flags: superreview?(jst)
Attachment #196017 - Flags: superreview+
Attachment #196017 - Flags: review?(jst)
Attachment #196017 - Flags: review+
Status: ASSIGNED → RESOLVED
Closed: 19 years ago
No longer depends on: 100499
Resolution: --- → FIXED
Depends on: 310068
Depends on: 310927
Depends on: 332238
Component: DOM: Core → DOM: Core & HTML
QA Contact: ian → general
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: