SitePoint Sponsor

User Tag List

Results 1 to 13 of 13

Thread: DOM puzzle

  1. #1
    SitePoint Member
    Join Date
    Nov 2003
    Location
    Scotland
    Posts
    8
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    DOM puzzle

    Working through Icarus's SitePoint article about the DOM, and find that the the example he gives at the start:
    <html>
    <head></head>
    <body bgcolor="white">
    <div id="a" style="font-family: Arial; color: white;
    background: black">Wassup?</div>
    <script language="JavaScript">
    var obj = document.childNodes[0].childNodes[1].childNodes[0];
    alert(obj.nodeName)
    obj.style.color = "red";
    </script>
    </body>
    </html>

    -- works in IE5.5 Win but not in Mozilla 1.5 - just downloaded yesterday, so should be current.

    Can anyone explain why? It displays the white on black text but doesn't change the colour and doesn't give any alert.

  2. #2
    SitePoint Member
    Join Date
    Nov 2003
    Location
    Scotland
    Posts
    8
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    More puzzlement.

    If I put the doctype into the page <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">, not only does it continue to do nothing in Moz, but it falls over in IE5.5.
    There's a script error saying document.childNodes.0 is not an object. (In the actual code it's childNodes[0] not childNodes.0, but that's what the error message says).

  3. #3
    ☆★☆★ silver trophy vgarcia's Avatar
    Join Date
    Jan 2002
    Location
    in transition
    Posts
    21,235
    Mentioned
    1 Post(s)
    Tagged
    1 Thread(s)
    Why not an alternate approach, like so:
    Code:
     var obj = document.getElementsByTagName("HTML").childNodes[1].childNodes[0];
     alert(obj.nodeName);
     obj.style.color = 'red';

  4. #4
    SitePoint Member
    Join Date
    Nov 2003
    Location
    Scotland
    Posts
    8
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    It was more the principle that puzzled me, as I thought Moz was more standards compliant than IE.

    Anyway I tried your code and got the same result:
    - works in IE without the doctype
    - falls over in IE with the doctype
    - Moz ignores the script completely

  5. #5
    I'll take mine raw silver trophy MikeFoster's Avatar
    Join Date
    Dec 2002
    Location
    Alabama, USA
    Posts
    2,560
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I first wrote this before anyone replied, so I'm looking at the replies now

    Hi Norman,

    I'm not critisizing Icarus' article, and I'm not a DOM expert, but just to try to answer your question...

    In his article he says...
    Let's alter the font colour of the text within the <div>. In Internet Explorer, this would typically be accomplished with

    <script language="JavaScript">
    document.all.a.style.color = "red";
    </script>
    So far so good. Note that he's getting a reference to the DIVs Element object via its id: "document.all.a".
    Now he says...
    Here's the code I would use in Mozilla:

    <script language="JavaScript">
    var obj = document.childNodes[0].childNodes[1].childNodes[0];
    obj.style.color = "red";
    </script>
    Now he's not using the id to get a reference to the object! Of course, here's how we do that via W3C DOM: "document.getElementById('a')"

    Let's look at this expression: "document.childNodes[0].childNodes[1].childNodes[0]". This makes assumptions about the objects in the DOM hierarchy (tree). Try the following in Moz or Firebird:

    Code:
    <html>
    <head>
    <script type='text/javascript'>
    window.onload = function()
    {
      alert(document.childNodes[0]);
      alert(document.childNodes[0].childNodes[1]);
      alert(document.childNodes[0].childNodes[1].childNodes[0]);
      var obj = document.childNodes[0].childNodes[1].childNodes[0];
      obj.style.color = "red";
    }
    </script>
    </head>
    <body bgcolor="white">
    <div id="a" style="font-family: Arial; color: white; background: black">Wassup?</div>
    </body>
    </html>
    Note that I've taken the code you posted, moved the script element into the head, and added calls to alert(). I've also put the script in the window.onload event handler because the DIV element may not actually exist until the load event occurs. The first alert displays "[object HTMLHtmlElement]", so this expression "document.childNodes[0]" resolves to a reference to the Element object corresponding to the HTML tag.

    In the article he assumes that the second child of the HTML element is the BODY element (the first being the HEAD element). This is correct in IE (in non-standards mode) - but not correct in any fully-DOM-compliant browser such as Mozilla. In my code above, you can see that the second alert displays "[object Text]" in Moz. We have resolved to a reference to a Text node. And this is correct because (looking at my code above) there is some white-space between the opening HTML tag and the opening HEAD tag - that white-space is represented in the DOM tree as a Text node, and it is actually the first child of HTML (document.childNodes[0].childNodes[0]). Likewise, there is white-space between the opening BODY tag and the opening DIV tag and this also becomes a Text node in the DOM tree.

    Let's look at the same code, but remove that whitespace:

    Code:
    <html><head>
    <script type='text/javascript'>
    window.onload = function()
    {
      alert(document.childNodes[0]);
      alert(document.childNodes[0].childNodes[1]);
      alert(document.childNodes[0].childNodes[1].childNodes[0]);
      var obj = document.childNodes[0].childNodes[1].childNodes[0];
      obj.style.color = "red";
    }
    </script>
    </head>
    <body bgcolor="white"><div id="a" style="font-family: Arial; color: white; background: black">Wassup?</div>
    </body>
    </html>
    This works!

    So in conclusion, when we make broad assumptions, they will usually come around to bite us.

  6. #6
    I'll take mine raw silver trophy MikeFoster's Avatar
    Join Date
    Dec 2002
    Location
    Alabama, USA
    Posts
    2,560
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Norman Lamont
    More puzzlement.

    If I put the doctype into the page <! DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">, not only does it continue to do nothing in Moz, but it falls over in IE5.5.
    There's a script error saying document.childNodes.0 is not an object. (In the actual code it's childNodes[0] not childNodes.0, but that's what the error message says).
    Excellent! In standards-compliant mode IE also represents the white-space as Text nodes.

    Using the DOM viewer in Moz let's you see the effect of white-space between elements, and how Moz represents that white-space as Text nodes.

  7. #7
    SitePoint Member
    Join Date
    Nov 2003
    Location
    Scotland
    Posts
    8
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for replying in some detail there.

    I tried your code and for me:
    - in IE5.5 it still gives an error message
    - in IE6 and Mozilla the alerts work but the text doesn't change to red as it should

    Why is it that in IE5.5 it works perfectly as long as the transitional doctype isn't included but falls over if the doctype is there? I could understand it if it was the strict doctype but ...

    I've posted my pages in case you want to look:
    http://www.normanlamont.com/dom/nodestest.htm nodestest2.htm and nodestest3.htm

  8. #8
    I'll take mine raw silver trophy MikeFoster's Avatar
    Join Date
    Dec 2002
    Location
    Alabama, USA
    Posts
    2,560
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi Norman,

    In both nodestest and nodestest2 there is still some whitespace between the opening BODY tag and the opening DIV tag. In nodestest3 there is no whitespace there.

    My second code post is not to show how it "should" be done, but rather just to illustrate how whitespace is represented as Text nodes in the DOM tree when the browser is in 'standards-compliant mode'.

    If an element has an id, then by all means use "document.getElementById(idString)" to get a reference to the object.

    There are times when we do need to traverse the DOM tree, and this when we need to remember that non-Element nodes may also be in the tree. For example in the following code the expression "oNode.nodeType == 1" checks to see if the node is of type ELEMENT_NODE instead of TEXT_NODE, COMMENT_NODE, etc. (reference: Node Interface)
    Code:
    /* xWalkTree()
       Perform a preorder traversal
       on the subtree starting at oNode
       and pass each Element node to fnVisit.
    */
    function xWalkTree(oNode, fnVisit)
    {
      if (oNode) {
        if (oNode.nodeType == 1) {fnVisit(oNode);}
        for (var c = oNode.firstChild; c; c = c.nextSibling) {
          xWalkTree(c, fnVisit);
        }
      }
    }
    Why is it that in IE5.5 it works perfectly as long as the transitional doctype isn't included but falls over if the doctype is there? I could understand it if it was the strict doctype but ...
    Reference IE6 Doctype Mode Switching. I'm not sure about how IE5.5 does this.

    Edit:

    replaced xWalkTree code with a version that's a little better commented
    Last edited by MikeFoster; Nov 19, 2003 at 13:04.

  9. #9
    SitePoint Member
    Join Date
    Nov 2003
    Location
    Scotland
    Posts
    8
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Smile

    Thanks - I can see I've got a lot to learn, and it's not as straightforward as I thought (it never is!)

    I just approached this because I was reading the 'intro to the DOM' article and wondered why I wasn't getting the same results. I'm not using it in earnest at the moment, but I will be as I bring the corporate intranet I work on towards standards compliance. It looks like my bosses will be ditching the requirement to support IE4 fairly soon, which allows us to take great steps forward in terms of standards. Which gives me a breathing space to learn about DOM.

    You mention Mozilla's DOM viewer - where do I find that?

    The best thing about this has been discovering these forums - the best I've come across for web development.

  10. #10
    011521 dbalsdon's Avatar
    Join Date
    Feb 2003
    Location
    North Of Scotland
    Posts
    444
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    to use the DOM viewer, press CTRL + SHIFT + i
    Daniel Balsdon
    My Site

  11. #11
    SitePoint Member
    Join Date
    Nov 2003
    Location
    Scotland
    Posts
    8
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ctrl-Shift-i does nothing for me. Do I have to enable it somewhere first?

  12. #12
    I'll take mine raw silver trophy MikeFoster's Avatar
    Join Date
    Dec 2002
    Location
    Alabama, USA
    Posts
    2,560
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Mozilla's DOM Inspector is found in the menus:
    "Tools | Web Development | DOM Inspector"

    When you installed Mozilla you had the option of "not" installing the debugger and inspector - so it's possible that they are not installed.

  13. #13
    SitePoint Member
    Join Date
    Nov 2003
    Location
    Scotland
    Posts
    8
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks - re-installed and got it now.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •