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

Discussion in 'Javascript' started by F. Da Costa, Jan 9, 2004.

  1. F. Da Costa

    F. Da Costa Guest

    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
     
    F. Da Costa, Jan 9, 2004
    #1
    1. Advertising

  2. "F. Da Costa" <> wrote in message
    news:3ffed021$0$331$4all.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.
     
    Richard Cornford, Jan 9, 2004
    #2
    1. Advertising

  3. "F. Da Costa" <> 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"),true);

    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 -
    DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
    'Faith without judgement merely degrades the spirit divine.'
     
    Lasse Reichstein Nielsen, Jan 9, 2004
    #3
  4. F. Da Costa

    F. Da Costa Guest

    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]);
    // 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);
    }
    }
     
    F. Da Costa, Jan 9, 2004
    #4
  5. F. Da Costa

    F. Da Costa Guest

    Lasse Reichstein Nielsen wrote:

    > "F. Da Costa" <> 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"),true);
    >
    > 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
     
    F. Da Costa, Jan 9, 2004
    #5
  6. "F. Da Costa" <> 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 -
    DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html>
    'Faith without judgement merely degrades the spirit divine.'
     
    Lasse Reichstein Nielsen, Jan 9, 2004
    #6
  7. "F. Da Costa" <> wrote in message
    news:3ffeec12$0$317$4all.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?

    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?


    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.
     
    Richard Cornford, Jan 9, 2004
    #7
  8. F. Da Costa

    F. Da Costa Guest

    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
     
    F. Da Costa, Jan 9, 2004
    #8
  9. F. Da Costa

    F. Da Costa Guest

    Re: IE 5+ bug? How to store complex objects whilst changing pages(forgot)

    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
     
    F. Da Costa, Jan 9, 2004
    #9
  10. Re: IE 5+ bug? How to store complex objects whilst changing pages (forgot)

    "F. Da Costa" <> wrote in message
    news:3fff33de$0$315$4all.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.
     
    Richard Cornford, Jan 12, 2004
    #10
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?R2FyeQ==?=
    Replies:
    2
    Views:
    462
    Wasi Rehman
    Oct 29, 2004
  2. =?Utf-8?B?UmFuZHkgR2FkaW5nYW4=?=

    "An error was encountered whilst attempting to start your session.

    =?Utf-8?B?UmFuZHkgR2FkaW5nYW4=?=, Jan 13, 2005, in forum: ASP .Net
    Replies:
    2
    Views:
    352
    =?Utf-8?B?UmFuZHkgR2FkaW5nYW4=?=
    May 10, 2005
  3. Alan Silver
    Replies:
    1
    Views:
    4,639
    Alan Silver
    Jul 6, 2005
  4. John
    Replies:
    5
    Views:
    597
    John Rivers
    Aug 25, 2005
  5. Richard
    Replies:
    5
    Views:
    394
    Hywel Jenkins
    Dec 28, 2004
Loading...

Share This Page