472,791 Members | 953 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 472,791 software developers and data experts.

IE 5+ bug? How to store complex objects whilst changing pages

Hi,

Does anybody know why IE5+ does *not* honour array objects (like a table)
across a session?

Example:
Frame A contains a var tableVar which is set via form Frame B (on init)
using top.A.tableVar = document.getElementById("someTable");

As long as Frame B is *not* 'refreshed/ reloaded' witk another page the
variable in Frame A is ok.
However, when the page is changed it just 'kills' the rows in tableVar.rows
(the lenght just turns to 0).

When tested with something simple like a String (instead of a table) the
above mechanism works as expected.

After two full days of mucking about this is strting to smell funny.
Does anybody have any idea/ suggestion as to the what and/ or why of this
behaviour.

TIA,
Fermin DCG
Jul 20 '05 #1
9 1867
"F. Da Costa" <da*****@xs4all.nl> wrote in message
news:3f*********************@news.xs4all.nl...
Does anybody know why IE5+ does *not* honour array objects
(like a table) across a session?
A table is not an array it is a host object (DOM Element).
Example:
Frame A contains a var tableVar which is set via form Frame B (on
init) using top.A.tableVar = document.getElementById("someTable");
For the best cross-browser support named frames are best referenced as
named properties of the global - frames - collection (of the parent
frame):-

top.frames.A.tableVar = . etc.

So you are assigning a reference to an element of a document in one
frame to a variable in another.
As long as Frame B is *not* 'refreshed/ reloaded' witk another page
the variable in Frame A is ok.
As it should be.
However, when the page is changed it just 'kills' the rows in
tableVar.rows (the lenght just turns to 0).
When you change the contents of a frame you destroy the document it
contains. All of the elements of that document become available for
garbage collection. Holding a reference to one of those elements in
another frame should (may) prevent the element itself and its
descendants from being garbage collected but as its document object has
been destroyed it is probably unrealistic to expect that element to
remain functional.

It is also usual for DOM implementations not to allow an Element (or
Node) from one document to be inserted in another (except using the
document.importNode method, which actually creates a copy of the
"imported" Node for the current document and leaves the original
unchanged).
When tested with something simple like a String (instead of a table)
the above mechanism works as expected.
Strictly the previous value assigned to the variable in the other frame
also "works", in the sense that it has been assigned a reference to an
object and it is still holding that value after the page has changed. It
is just that the object referred to has been radically altered by the
fact that its document has been destroyed (in addition, its global
context/window(frame) object has also been distorted).
After two full days of mucking about this is strting to smell funny.
Does anybody have any idea/ suggestion as to the what and/ or
why of this behaviour.


Trying to store a reference to a table is a shortcut to trying to store
the information within that table, probably the best solution is to
extract the required information from the table and store that in a
JavaScript object belonging to frame A. Probably an object customised to
ease the process of restoring/inserting the information to new elements
created in the other frame.

Richard.
Jul 20 '05 #2
"F. Da Costa" <da*****@xs4all.nl> writes:
Does anybody know why IE5+ does *not* honour array objects (like a
table) across a session?
Tables are not arrays.
Example:
Frame A contains a var tableVar which is set via form Frame B (on
init) using top.A.tableVar = document.getElementById("someTable");
You store a table element (not an array) belonging to the document in
Frame B. DOM elements are bound to the document that created them,
and can't be inserted into other documents. It is an "active" element
that is represented directly in the page, and reflects all changes
made ....
As long as Frame B is *not* 'refreshed/ reloaded' witk another page
the variable in Frame A is ok.
However, when the page is changed it just 'kills' the rows in
tableVar.rows (the lenght just turns to 0).
.... including removing all children when the page is unloaded.
There is no longer a table in that document, and it sure doesn't
have children, so no rows.
When tested with something simple like a String (instead of a table)
the above mechanism works as expected.
Strings are simple objects. DOM elements are not. They won't survive
the death of their page any more than the document.images collection
would.
After two full days of mucking about this is strting to smell funny.
Does anybody have any idea/ suggestion as to the what and/ or why of
this behaviour.


What you can do is to store a clone of the table element instead of
the element itself. If you use the correct document.importNode method,
it should make a clone that is linked to the document you store it in.

top.frames['A'].myTableClone =
top.frames['A'].document.importNode(getElementById("MyTableId"),t rue);

And when you need to use it again:

var myTableClone = document.importNode(top.frames['A'].myTableClone,true);

(but notice that document.importNode is DOM 2, so IE doesn't support it)

/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Jul 20 '05 #3
Richard Cornford wrote:
A table is not an array it is a host object (DOM Element). It most certainly is
For the best cross-browser support named frames are best referenced as
named properties of the global - frames - collection (of the parent
frame):- Point taken but judging from you comment this is not where the issue lies
top.frames.A.tableVar = . etc.

So you are assigning a reference to an element of a document in one
frame to a variable in another. Correct
When you change the contents of a frame you destroy the document it
contains. All of the elements of that document become available for
garbage collection. Holding a reference to one of those elements in
another frame should (may) prevent the element itself and its
descendants from being garbage collected but as its document object has
been destroyed it is probably unrealistic to expect that element to
remain functional. Ahh, I take your point but wouldn't that imply that this should not work
with Gecko based browsers either? Which (unfortunately?) it does!
It is also usual for DOM implementations not to allow an Element (or
Node) from one document to be inserted in another (except using the
document.importNode method, which actually creates a copy of the
"imported" Node for the current document and leaves the original
unchanged). Ok, updating my DOM knowledge here. Does this mean that every frame has got
its own DOM or is the DOM still 'defined at browser level' if you wish and
are the frames just nodes in the overall structure?
I was under the impression that the latter is the case.
When tested with something simple like a String (instead of a table)
the above mechanism works as expected.
Strictly the previous value assigned to the variable in the other frame
also "works", in the sense that it has been assigned a reference to an
object and it is still holding that value after the page has changed. It
is just that the object referred to has been radically altered by the
fact that its document has been destroyed (in addition, its global
context/window(frame) object has also been distorted).

In summary: the variable that holds the reference indeed still contains it.
Because 'further down' in the reference part of it is 'linked' to a
'disappearing' document this part becomes 'stuffed up.
I (think) I can follow the reasoning but I'm still not getting the fact
that Gecko is *not* compliant with *this* behaviour.
Actually, should it not be irrelevant how complex a structure is? Either
you loose cit or you don't. the table as a whole is part of the document so
wouldn't it be more logical for it to disappear as a whole and not just its
rows?

Trying to store a reference to a table is a shortcut to trying to store
the information within that table, Absolutely correct, basically its a state keeping issue. probably the best solution is to
extract the required information from the table and store that in a
JavaScript object belonging to frame A. Probably an object customised to
ease the process of restoring/inserting the information to new elements
created in the other frame.


Ok, couldn't cloneNode be used to basically 'do' this.
On init one just clones the 'skeleton'
On subsequent modification one just clones the required part and inserts it
into the static structure.

IF the above would hold can I than still 'replace' the not required table
coming in on the new page with the 'stored' static one or would that result
in funny behaviour as well.

Following the code (part of the static frame) used by the 'dynamic' frame
to modify the structure shown.

Thx for the reply.

=============================================
var _staticTable;
var _tbodyRows;

/**
* This function is responsible for inserting a new tBody in an extisting
table.
* @param win = the window from where the function is called (mainContent)
* @param table = the ID of the table where the tbody needs to be inserted
*/
function createTbody(win, tBodyID) {
var windoc = win.document;
var myDiv = windoc.getElementById("doc");

// creates/ get an element of type TABLE
if (tBodyID=="" || !_staticTable) {
_staticTable = windoc.getElementById("treeTable");
return;
}
else {
var defaultTable = windoc.getElementById("treeTable");
myDiv.replaceChild(_staticTable, defaultTable);
}

// creates an element whose tag name is TBODY
var mytablebody = windoc.getElementById(tBodyID);
// creating all cells within the rows
for(var j=0, rLen=_tbodyRows.length; j<rLen; j++) {
// creates an element whose tag name is TR
var mycurrent_row=windoc.createElement("TR");

// start working on the columns
for(var i=0, cLen=_tbodyRows[0].length; i < cLen; i++) {
// creates an element whose tag name is TD
var mycurrent_cell=windoc.createElement("TD");
// creates a Text Node
var currenttext=windoc.createTextNode(_tbodyRows[j][i]);
// appends the Text Node we created into the cell TD
mycurrent_cell.appendChild(currenttext);
// appends the cell TD into the row TR
mycurrent_row.appendChild(mycurrent_cell);
}
// appends the row TR into TBODY
mytablebody.appendChild(mycurrent_row);
}
}
Jul 20 '05 #4
Lasse Reichstein Nielsen wrote:
"F. Da Costa" <da*****@xs4all.nl> writes:

Does anybody know why IE5+ does *not* honour array objects (like a
table) across a session?

Tables are not arrays.

I'll be more carefull in the future with my naming (Richard Cornford also
chewed me on this one ;)).
Example:
Frame A contains a var tableVar which is set via form Frame B (on
init) using top.A.tableVar = document.getElementById("someTable");

You store a table element (not an array) belonging to the document in
Frame B. DOM elements are bound to the document that created them,
and can't be inserted into other documents. It is an "active" element
that is represented directly in the page, and reflects all changes
made ....

This is fine because I do not want to move it to another document 'to be
shown'.
As long as Frame B is *not* 'refreshed/ reloaded' witk another page
the variable in Frame A is ok.
However, when the page is changed it just 'kills' the rows in
tableVar.rows (the lenght just turns to 0).

.... including removing all children when the page is unloaded.
There is no longer a table in that document, and it sure doesn't
have children, so no rows.
When tested with something simple like a String (instead of a table)
the above mechanism works as expected.


Strings are simple objects. DOM elements are not. They won't survive
the death of their page any more than the document.images collection
would.

That might be the case but why then would the Gecko browsers (Moz 1.6b + FB
0.7+ ) not have a problem with this. They hold on to the structure as
stored to be reused at a later stage when required in the page the user is
looking at.
After two full days of mucking about this is strting to smell funny.
Does anybody have any idea/ suggestion as to the what and/ or why of
this behaviour.

What you can do is to store a clone of the table element instead of
the element itself. If you use the correct document.importNode method,
it should make a clone that is linked to the document you store it in.

top.frames['A'].myTableClone =
top.frames['A'].document.importNode(getElementById("MyTableId"),t rue);

And when you need to use it again:

var myTableClone = document.importNode(top.frames['A'].myTableClone,true);

(but notice that document.importNode is DOM 2, so IE doesn't support it)

Ahh, but you probably guessed as well. *This* is where the problem lies. I
need a way to dynamically build a potentially biggish table without
bothering the server too much.

Would the cloneNode be a possibility instead?

Thx 4 your effort (again).

Fermin DCG
Jul 20 '05 #5
"F. Da Costa" <da*****@xs4all.nl> writes:
Ahh, I take your point but wouldn't that imply that this should not
work with Gecko based browsers either? Which (unfortunately?) it does!
There is nothing in the DOM specification that says what should happen
when a browser unloads a page. The DOM specification only talks about
what you can do with nodes, and nothing about browsers. When the
browser loads the document, it creates a DOM compliant object
structure, and when it unloads the document, it ... well, it does
whatever it wants to do. It seems IE destroys the document structure
by removing all children from the parent (probably in order to better
garbage collect the memory). And apparently Mozilla doesn't change the
document structure, it just forgets it. Neither is wrong.
Ok, updating my DOM knowledge here. Does this mean that every frame
has got its own DOM or is the DOM still 'defined at browser level' if
you wish and are the frames just nodes in the overall structure?
I was under the impression that the latter is the case.
The DOM is a specification of how some objects should behave. The
nodes that are created by the browser in accordance with this
specification are just host objects with references to each other.

There is one DOM, it's published by W3C. What I think you are thinking
of is the document's DOM node tree, which is a tree-like structure of
DOM (compliant) Node objects.

These nodes can refer to each other between windows, but each
document's node tree can only contain nodes created by that document
(either when loaded, or using that document's createElement or
createTextNode methods).

Actually, should it not be irrelevant how complex a structure is?
Either you loose cit or you don't. the table as a whole is part of the
document so wouldn't it be more logical for it to disappear as a whole
and not just its rows?
The rows didn't disappear. The link between the table element node and
its child nodes have been severed, just as I'll bet the table node's
parentNode reference is also null. But the table element's node object
must still exist, *because you have a reference to it*. In Javascript,
and indeed most garbage collected object oriented langauges, a reference
to an object will always point to that object. The object can't be
destroyed, because then your reference would point to ... what?
Ok, couldn't cloneNode be used to basically 'do' this.


It will make a clone that is still attached to the same document.
That is why I suggested importNode, because the clone it makes
is linked to a different document.

/L
--
Lasse Reichstein Nielsen - lr*@hotpop.com
DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
'Faith without judgement merely degrades the spirit divine.'
Jul 20 '05 #6
"F. Da Costa" <da*****@xs4all.nl> wrote in message
news:3f*********************@news.xs4all.nl...
<snip>
When you change the contents of a frame you destroy the document it
contains. All of the elements of that document become available for
garbage collection. Holding a reference to one of those elements in
another frame should (may) prevent the element itself and its
descendants from being garbage collected but as its document object
has been destroyed it is probably unrealistic to expect that
element to remain functional.
Ahh, I take your point but wouldn't that imply that this should not
work with Gecko based browsers either? Which (unfortunately?) it does!
No, it implies that you should have no expectation of it working with
Gecko browsers, and if it does you should have no expectation of it
continuing to work with Gecko browsers. When it comes to host objects
(which DOM elements are) the ECMA Script specifications don't get
involved so what happens is largely up to the implementers (at least in
the areas not covered by the W3C DOM specifications/recommendations (and
even then only the Core DOM is mandatory)).

If it works with Gecko browsers now then you got lucky. That happens: I
remember a post from someone who wanted to create a cross-frame pop-up
menu and had discovered that creating/appending an absolutely positioned
DIV element in/to the topmost frameset document in one Mozilla release
allowed that DIV to float across frame boundaries, displaying over all
of them. The resulting DOM was invalid as DIVs cannot be children of
FRAMESETs and the attempt should have thrown a HIERARCHY_REQUEST_ERR
exception. The previous versions of Mozilla had not allowed it, and the
subsequent versions did not allow it, so I don't imagine the menu script
he had written using it lasted very long.
It is also usual for DOM implementations not to allow an Element (or
Node) from one document to be inserted in another (except using the
document.importNode method, which actually creates a copy of the
"imported" Node for the current document and leaves the original
unchanged).

Ok, updating my DOM knowledge here. Does this mean that every frame
has got its own DOM or is the DOM still 'defined at browser level'
if you wish and are the frames just nodes in the overall structure?
I was under the impression that the latter is the case.
There are a number of different things that are referred to as DOM
(often incorrectly ), what I am referring to above as "DOM
implementations" are implementations of the W3C Core DOM specification
(which, in web browsers, usually include the W3C HTML DOM and other W3C
standards like events). The W3C DOM specifications *only* cover a -
Document - object and its descendants/content, they say noting about
window/frame/global objects. Web Browsers have an Object Model that
(with a frameset) does represent a hierarchical structure of
window/frame/global objects and those objects each contain a document
object that (more or less, mostly more with modern browsers) implements
the W3C DOM.

<snip>In summary: the variable that holds the reference indeed still contains
it. Because 'further down' in the reference part of it is 'linked' to a
'disappearing' document this part becomes 'stuffed up.
I (think) I can follow the reasoning but I'm still not getting the fact
that Gecko is *not* compliant with *this* behaviour.
Actually, should it not be irrelevant how complex a structure is? Eitheryou loose cit or you don't. the table as a whole is part of the documentso wouldn't it be more logical for it to disappear as a whole and not
just its rows?
This behaviour is outside of any specifications so you are just
experiencing differences in implementations of the browser object model,
the W3C DOM and the garbage collecting system. Nobody is right or wrong
they have just made different decisions about how to implement their
browsers (and probably included different bugs).

But if you are examining the residual structure of elements under the
table only via its - rows - collection then you haven't verified that
the rows are absent, just that the - rows - collection is no longer
working. If you checked - firstChild - you might find that they are
still there. Then again you might find that the rows are gone. It
doesn't matter, once the page in the other frame has unloaded you have
no grounds for expecting a reference to an element in the document from
that frame to be in any way useful.

<snip>Ok, couldn't cloneNode be used to basically 'do' this.
I don't think cloneNode is going to help at all as it is a method of the
Node interface and a clone of a Node that belongs to a document will be
a Node that belongs to the same document. only the importNode method of
another document could do the job, and as Lasse pointed out, IE doesn't
support it yet.
On init one just clones the 'skeleton'
On subsequent modification one just clones the required part and
inserts it into the static structure. IF the above would hold can I than still 'replace' the not required
table coming in on the new page with the 'stored' static one or
would that result in funny behaviour as well.

<snip>

Having used insertNode to clone a Node into a document in frame A for
storage you would then have to use insertNode on the newly loaded
document to put a clone of the stored node into it.

Richard.
Jul 20 '05 #7
Can I just thank you guys, Lasse & Richard, for explaining this 'swampy
matter' to me (and the list).
Learned two things today of which one is to try and be more specific about
my wording re. elements, objects, references etc.

Richard Cornford wrote:
Trying to store a reference to a table is a shortcut to trying to store
the information within that table, probably the best solution is to
extract the required information from the table and store that in a
JavaScript object belonging to frame A. Probably an object customised to
ease the process of restoring/inserting the information to new elements
created in the other frame.

This probably sounds like the only way to go.
So now i'm just left with one question & that is:
What would be the performance penalty when using a self-constructed
(state)object to populate a document (esp) when we start to get into bigger
(2000+ rows) structures.

It would have to put against an increase in traffic plus addirtional drain
on the server, producing full documents (instead of parts thereof)

I'm just putting this forward because I would not have a clue as to the
true processing potential of JS.

Thx again for your troubles, appreciated.

Fermin
Jul 20 '05 #8
F. Da Costa wrote:
So now i'm just left with one question & that is: Correction, its actually two:
Am i right in assuming that any HTMLXyzElement created via the
createElement method *belongs* to the document where created and that these
items cannot be relieds upon?

What would be the performance penalty when using a self-constructed
(state)object to populate a document (esp) when we start to get into
bigger (2000+ rows) structures.

It would have to put against an increase in traffic plus addirtional
drain on the server, producing full documents (instead of parts thereof)

I'm just putting this forward because I would not have a clue as to the
true processing potential of JS.

Thx again for your troubles, appreciated.

Fermin

Jul 20 '05 #9
"F. Da Costa" <da*****@xs4all.nl> wrote in message
news:3f*********************@news.xs4all.nl...
Correction, its actually two:
Am i right in assuming that any HTMLXyzElement created via the
createElement method *belongs* to the document where created
Yes.
and that these items cannot be relieds upon?


That depends on what you mean by "relied upon". In the context of the
previous discussion in this thread the issues of element ownership would
be identical.
What would be the performance penalty when using a
self-constructed (state)object to populate a document (esp)
when we start to get into bigger (2000+ rows) structures.
That is going to depend on haw the Object is implemented. On a
reasonably fast PC you can probably create/insert 2000 elements faster
than you can download the HTML that would describe them. But I would
always recommend having a server-side fall-back for this type of thing
anyway and letting the client-side script ease the burden on the server
when that is practical. And that would give you a system that was not
dependent on dynamic DOM support and so cross browser.
It would have to put against an increase in traffic plus
addirtional drain on the server, producing full documents
(instead of parts thereof)

I'm just putting this forward because I would not have a clue
as to the true processing potential of JS.


JavaScript is an interpreted scripting language so it should not be
expected to be fast but the DOM methods are implemented in native code
and they will be doing the bulk of the work. It is certainly possible to
significantly undermine the performance of a script by coding it
inefficiently and therefor a lot to be gained with efficient code (at
least when performance is an issue).

Richard.
Jul 20 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
by: Rolf Hemmerling | last post by:
Hello ! Beginner's question: What ist the easiest way to store and save objects in a file generated by a C++ program, by using the "standard C++ library" and/or "Standard Template Library (...
3
by: Alex | last post by:
I'm having a problem porting an ASP solution to ASPX. In the ASP solution I'm accessing a DCOM server, create sub DCOM objects and call functions from VB script on the ASP pages. The DCOM object...
5
by: Trail Monster | last post by:
Ok, I've been searching the net now for several days and can't find how to do this anywhere. Version: VS 2005 Professional Release, 2.0 Framework Background: I have a complex business object...
4
by: William | last post by:
After much frustration I was able to update my data store via code only. Using the data adapter was the only way I was able to set up all the objects written in my code. Basically, I cheated by...
2
by: PeteZ | last post by:
Can someone help me here. I'm having trouble finding details on how complex objects (eg. an object created in a code behind page that has imbedded object references, collections etc imbedded in...
3
by: Indiresh | last post by:
Hi all, I have a problem downloading web pages to my local system. I am using the HttpebRequest class to query a web site and get the response from the same. UndNow, when i asy a web page, all...
8
by: Lauren the Ravishing | last post by:
Hi, In ASP, is it absolutely necessary to set an object to Nothing after being used? set myObj = server.createObject("myDLL.myClass") call myObj.useClass set myObj = Nothing <--- can I...
47
by: Max | last post by:
Due to the behaviour of a particular COM object, I need to ensure that a request for a particular ASP page is finalized before another request for the page is processed. Does IIS have a way to...
16
by: Wayne | last post by:
I've read that one method of repairing a misbehaving database is to save all database objects as text and then rebuild them from the text files. I've used the following code posted by Lyle...
0
linyimin
by: linyimin | last post by:
Spring Startup Analyzer generates an interactive Spring application startup report that lets you understand what contributes to the application startup time and helps to optimize it. Support for...
0
by: erikbower65 | last post by:
Here's a concise step-by-step guide for manually installing IntelliJ IDEA: 1. Download: Visit the official JetBrains website and download the IntelliJ IDEA Community or Ultimate edition based on...
0
by: kcodez | last post by:
As a H5 game development enthusiast, I recently wrote a very interesting little game - Toy Claw ((http://claw.kjeek.com/))。Here I will summarize and share the development experience here, and hope it...
14
DJRhino1175
by: DJRhino1175 | last post by:
When I run this code I get an error, its Run-time error# 424 Object required...This is my first attempt at doing something like this. I test the entire code and it worked until I added this - If...
0
by: Rina0 | last post by:
I am looking for a Python code to find the longest common subsequence of two strings. I found this blog post that describes the length of longest common subsequence problem and provides a solution in...
5
by: DJRhino | last post by:
Private Sub CboDrawingID_BeforeUpdate(Cancel As Integer) If = 310029923 Or 310030138 Or 310030152 Or 310030346 Or 310030348 Or _ 310030356 Or 310030359 Or 310030362 Or...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
0
by: lllomh | last post by:
How does React native implement an English player?
0
by: Mushico | last post by:
How to calculate date of retirement from date of birth

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.