DOM initialisation in IE 6

Discussion in 'Javascript' started by abcd_68@yahoo.co.uk, Jan 12, 2006.

  1. Guest

    All,

    First off please note that I'm a novice at Javascript so please bear
    with me.
    Second, I did look at FAQs, this group, the web etc. but I'm still
    stuck.

    Problem is the following. I've got a fairly complex (for my abilities
    at least) page with nested tables. Think of it as a small spreadsheet,
    in which I have to perform computations (in Javascript of course) on a
    per row basis and compute the grand totals in the bottom line. All the
    rows are contained in a big form the will eventually be submitted. Upon
    page loading I need to fill up arrays of references to the various
    input elements so as to be able to quickly recompute totals in the
    bottom line when the user changes some value. I do so by exploiting the
    DOM, using constructs such as document.getElementById(), childNodes,
    parent, etc.

    So far so good and, as a matter of the fact, everything works perfectly
    under firefox 1.5. Not so under IE 6 (on the same machine, running
    WinXP SP2). Problem lies in the array initialisation. At first I used a
    simple onload() function which works just fine under FF. This was not
    working on IE so I set up an init() function (changed names just in
    case, but the automatic association between event name and function
    name does not seem to work under IE anyway) and tried all of the
    following (one at a time of course):
    <body onload=init>
    window.onload = function () {init();}
    window.onload = init
    window.addEventListener('load', init, true|false)
    window.attachEvent('onload', init)

    Apart from addEventListener which IE frowns upon (I knew it wouldn't
    work but I tried out of desperation), all the others "work" i.e., the
    init function is actually called (my debugging alerts pop up). Problem
    is, in all cases (under IE) said function fails to properly initialise
    the arrays, issuing errors such as "childNodes is null or not an
    object" and the like.

    In my (possibly naive) interpretation, the root of the problem is that
    when init() is called the DOM hasn't been properly initialised yet. I
    try to retrieve elements by id but those elements are not completely
    formed e.g., they have no children. However, this is against all that I
    read about onload being fired *after* everything has been properly set
    up. And again, everything is working just fine under FF so the object
    references I use do make sense.

    I'm stuck... Can you help?

    Thanks a lot,
    Andy
    , Jan 12, 2006
    #1
    1. Advertising

  2. RobG Guest

    wrote:
    [...]
    > Problem is the following. I've got a fairly complex (for my abilities
    > at least) page with nested tables. Think of it as a small spreadsheet,
    > in which I have to perform computations (in Javascript of course) on a
    > per row basis and compute the grand totals in the bottom line. All the
    > rows are contained in a big form the will eventually be submitted. Upon
    > page loading I need to fill up arrays of references to the various
    > input elements so as to be able to quickly recompute totals in the
    > bottom line when the user changes some value. I do so by exploiting the
    > DOM, using constructs such as document.getElementById(), childNodes,
    > parent, etc.
    >
    > So far so good and, as a matter of the fact, everything works perfectly
    > under firefox 1.5. Not so under IE 6 (on the same machine, running
    > WinXP SP2). Problem lies in the array initialisation. At first I used a
    > simple onload() function which works just fine under FF. This was not
    > working on IE so I set up an init() function (changed names just in
    > case, but the automatic association between event name and function
    > name does not seem to work under IE anyway) and tried all of the


    There is nothing that says a function called 'init' will be called by
    window.onload simply because it exists and is called 'init'. You have
    to assign either a reference or function to the window onload property,
    the name is irrelevant (provided it meets the criteria for JavaScript
    function names).


    > following (one at a time of course):
    > <body onload=init>

    ---------------^^^^^
    Probably just a posting typo:

    <body onload="init();">


    > window.onload = function () {init();}
    > window.onload = init
    > window.addEventListener('load', init, true|false)
    > window.attachEvent('onload', init)
    >
    > Apart from addEventListener which IE frowns upon (I knew it wouldn't
    > work but I tried out of desperation), all the others "work" i.e., the
    > init function is actually called (my debugging alerts pop up). Problem
    > is, in all cases (under IE) said function fails to properly initialise
    > the arrays, issuing errors such as "childNodes is null or not an
    > object" and the like.
    >
    > In my (possibly naive) interpretation, the root of the problem is that
    > when init() is called the DOM hasn't been properly initialised yet. I


    Or you are doing something that prevents IE from seeing the childNodes
    but not Firefox. A recent issue was that using innerHTML on the title
    element caused similar behaviour (but that may not be your problem).

    AFAIK, onload works as expected in IE.


    > try to retrieve elements by id but those elements are not completely
    > formed e.g., they have no children. However, this is against all that I
    > read about onload being fired *after* everything has been properly set
    > up. And again, everything is working just fine under FF so the object
    > references I use do make sense.
    >
    > I'm stuck... Can you help?


    Post a URL or a minimal example that displays the behaviour.



    --
    Rob
    RobG, Jan 13, 2006
    #2
    1. Advertising

  3. Guest

    Hi Rob,

    thanks for your reply.

    > There is nothing that says a function called 'init' will be called by
    > window.onload simply because it exists and is called 'init'.


    True, if the function is called 'init'. Apparently not so if it bears
    the name of an event, as documented in the Javascript bible 5th edition
    (the only Javascript book I have at hand, don't know how reliable it
    is), on page 168: "[...] you can define the action of an event handler
    by defining a function with the event handler's name." Which does work
    under FF.

    > Post a URL or a minimal example that displays the behaviour.


    I can't post a URL due to the usual copyright stuff, I'll try to
    isolate a minimal example.

    Thanks
    , Jan 13, 2006
    #3
  4. RobG Guest

    wrote:
    > Hi Rob,
    >
    > thanks for your reply.
    >
    >
    >>There is nothing that says a function called 'init' will be called by
    >>window.onload simply because it exists and is called 'init'.

    >
    >
    > True, if the function is called 'init'. Apparently not so if it bears
    > the name of an event, as documented in the Javascript bible 5th edition
    > (the only Javascript book I have at hand, don't know how reliable it
    > is), on page 168: "[...] you can define the action of an event handler
    > by defining a function with the event handler's name." Which does work
    > under FF.


    Yes, it 'works'. Danny Goodman's book is not held in high regard,
    search the archives.

    I haven't read the book - if you mean assigning a function to the value
    of the window object's onload property using:

    function onload(){alert('hey');}


    there may well be technical reasons why that is never done. I've never
    seen it and don't have the knowledge to know if it's good or bad. But I
    suspect that the following are much more acceptable (as well as being
    far more common) for a reason:

    window.onload = funcRef;

    or

    window.onload = function(){
    // function body
    }


    There are a couple of reasons for using window.onload rather than just
    onload:

    1. The lookup is faster (imperceptibly, but it all counts);
    2. There is no doubt about the scope of the function, it
    is unequivocally attached to the window object so better
    maintenance.


    The use of addEventListener/attachEvent is considered best of all. It
    should be used if there is any doubt whether there might already be a
    function assigned to window.onload (e.g. if a function within a script
    library wants to attach a function to onload) - you can add/remove
    functions without affecting others that might be attached.


    [...]


    --
    Rob
    RobG, Jan 13, 2006
    #4
  5. RobG wrote:

    > [...] if you mean assigning a function to the value
    > of the window object's onload property using:
    >
    > function onload(){alert('hey');}
    >
    >
    > there may well be technical reasons why that is never done. I've never
    > seen it and don't have the knowledge to know if it's good or bad.


    I think it is bad for it assumes that the Global Object is the object
    referred to by `window' and that variable instantiation will allow for
    replacing a property of that _host_ object. See ES3, sections 10.1.3,
    pt. 2 and 10.2.1.


    PointedEars
    Thomas 'PointedEars' Lahn, Jan 13, 2006
    #5
  6. Guest

    Hi,

    I finally solved the problem. It had nothing to do with DOM
    initialisation at all. All the onload/setEventHandler/etc. stuff works
    ok. The problem (predictably) was an error on my part.

    Apparently IE and FF treat a table's children differently. Under IE the
    firstChild of a table is the first row, whereas under FF it's something
    else (maybe a a text node). So what happened was that one browser
    needed a firstChild, while the other required childNodes[1].

    I fixed the problem using:
    var feeTable = document.getElementById('feeTable');
    var rows = feeTable.rows; //instead of firstChild etc.
    which works ok under both. This was probably obvious to all of you in
    this ng but as I said I'm a Javascript novice.

    Thanks a lot
    Andy
    , Jan 13, 2006
    #6
  7. RobG Guest

    wrote:
    > Hi,
    >
    > I finally solved the problem. It had nothing to do with DOM
    > initialisation at all. All the onload/setEventHandler/etc. stuff works
    > ok. The problem (predictably) was an error on my part.
    >
    > Apparently IE and FF treat a table's children differently. Under IE the
    > firstChild of a table is the first row, whereas under FF it's something
    > else (maybe a a text node). So what happened was that one browser
    > needed a firstChild, while the other required childNodes[1].


    The firstchild of a table is never a TR, it is always either a CAPTION, COL
    or COLGROUP, THEAD, TFOOT or TBODY.

    A tbody must always be present, it will be added by the browser if you don't.


    >
    > I fixed the problem using:
    > var feeTable = document.getElementById('feeTable');
    > var rows = feeTable.rows; //instead of firstChild etc.
    > which works ok under both. This was probably obvious to all of you in
    > this ng but as I said I'm a Javascript novice.


    It's actually a consequence of your HTML, you discovered it because of how
    you were trying to access elements by traversing the DOM tree. Firefox
    will insert text nodes where there is whitespace between elements[1], IE
    generally doesn't. For example given the HTML:

    <tr>
    <td> ... </td>
    </tr>

    In Firefox the TR will have three child nodes, #text, TD then #text. In IE,
    it will have just one - the TD. If the HTML was:

    <tr><td> ... </td></tr>

    both browsers will give the TR just one child - the TD. Using the rows
    collection is much better.

    Be aware that there might be browsers that don't support the rows
    collection, there is at least one reasonably modern browser (Safari 1.0.3 -
    Mac OS 10.2.8) that only partially supports the row cells collection (fixed
    in later versions). There are a number of mobile browsers that seem to
    have very patchy W3C DOM support (even though they may be well be fully
    compliant with JavaScript 1.5).

    You could perhaps use getElementsByTagName or walk down the DOM tree
    testing nodeName, tagName or nodeType.


    1. "Between" being either:

    - after the opening tag of an element and before the
    opening tag of a child node,

    - after the closing tag of an element and before
    the opening tag of a sibling, or

    - after the closing tag of an element and before the
    closing tag of its parent element.

    Use the Firefox DOM inspector to see where they are, there will be other
    #text nodes amongst element contents.



    --
    Rob
    RobG, Jan 13, 2006
    #7
    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. Thorsten Meininger
    Replies:
    0
    Views:
    439
    Thorsten Meininger
    Jul 28, 2004
  2. Thorsten Meininger
    Replies:
    0
    Views:
    503
    Thorsten Meininger
    Jul 28, 2004
  3. mike
    Replies:
    1
    Views:
    1,132
    Martin Honnen
    Nov 20, 2004
  4. Replies:
    0
    Views:
    545
  5. Tim Clacy
    Replies:
    8
    Views:
    392
    Tim Clacy
    May 30, 2006
Loading...

Share This Page