Recursive function : driving me crazy...

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Phil

    Recursive function : driving me crazy...

    Hello
    I'm trying to display all DIV tags of a document :
    Example :

    + <DIV id="1">
    - <DIV id="1-1"></DIV>
    </DIV>

    + <DIV id="2">
    - <DIV id="2-1"></DIV>
    + <DIV id="2-2"></DIV>
    - <DIV id="2-2-1"></DIV>
    - <DIV id="2-2-2"></DIV>

    etc...

    I can retrieve all DIV using getElementsByTa gName, but I don't know how
    deep they can be nested.
    I have no idea how to store informations such as : does a div has children
    ? if yes, how many ? in turn do the children have children ? At what level
    is each DIV ? etc
    Only a recursive function could do that, I think

    Any help appreciated
    Thanks.



  • McKirahan

    #2
    Re: Recursive function : driving me crazy...

    "Phil" <pasdemail@pasd email.com> wrote in message
    news:Lo6dnSbfUt-JinGiRVn-gg@giganews.com ...[color=blue]
    > Hello
    > I'm trying to display all DIV tags of a document :
    > Example :
    >
    > + <DIV id="1">
    > - <DIV id="1-1"></DIV>
    > </DIV>
    >
    > + <DIV id="2">
    > - <DIV id="2-1"></DIV>
    > + <DIV id="2-2"></DIV>
    > - <DIV id="2-2-1"></DIV>
    > - <DIV id="2-2-2"></DIV>
    >
    > etc...
    >
    > I can retrieve all DIV using getElementsByTa gName, but I don't know how
    > deep they can be nested.
    > I have no idea how to store informations such as : does a div has[/color]
    children[color=blue]
    > ? if yes, how many ? in turn do the children have children ? At what level
    > is each DIV ? etc
    > Only a recursive function could do that, I think
    >
    > Any help appreciated
    > Thanks.[/color]


    Your example above was missing a </DIV> tag and had another misplaced.

    I may not understand your problem.

    You say that you are "trying to display all DIV tags of a document" and that
    you "can retrieve all DIV using getElementsByTa gName"; what does it matter
    how deep they are nested?

    Below is a page that displays the id's of all <DIV> tags. Watch for
    word-wrap.

    <html>
    <head>
    <title>getElems .htm</title>
    </head>
    <body>
    <DIV id="1">
    <DIV id="1-1"></DIV>
    </DIV>
    <DIV id="2">
    <DIV id="2-1"></DIV>
    <DIV id="2-2">
    <DIV id="2-2-1"></DIV>
    <DIV id="2-2-2"></DIV>
    </DIV>
    </DIV>
    <script language="javas cript" type="text/javascript">
    <!--
    var divs = document.getEle mentsByTagName( "DIV");
    var what = "DIV tags:\n";
    for (var i=0; i<divs.length; i++) {
    what += "\n" + divs[i].id;
    }
    alert(what);
    // -->
    </script>
    </body>
    </html>


    Comment

    • Phil

      #3
      Re: Recursive function : driving me crazy...

      [color=blue]
      > I may not understand your problem.
      >
      > You say that you are "trying to display all DIV tags of a document" and[/color]
      that[color=blue]
      > you "can retrieve all DIV using getElementsByTa gName"; what does it matter
      > how deep they are nested?
      >
      > Below is a page that displays the id's of all <DIV> tags. Watch for
      > word-wrap.
      >[/color]

      Thanks for your example, but I can already made this. What I want is really
      displaying (document.write ) the tree, with nodes, children and so forth
      (Missing closing tags is not the point, I write this on the fly and I know
      they are missing)

      So if a div has children, I need to write the + sign, then the nested
      children (if any) indented, etc
      + <DIV id="2">
      - <DIV id="2-1"></DIV>
      + <DIV id="2-2"></DIV>
      - <DIV id="2-2-1"></DIV>
      - <DIV id="2-2-2"></DIV>
      </DIV>




      Comment

      • Lasse Reichstein Nielsen

        #4
        Re: Recursive function : driving me crazy...

        "Phil" <pasdemail@pasd email.com> writes:
        [color=blue]
        > Thanks for your example, but I can already made this. What I want is really
        > displaying (document.write ) the tree, with nodes, children and so forth
        > (Missing closing tags is not the point, I write this on the fly and I know
        > they are missing)[/color]

        I'll just write it as a string here, I'm sure you can convert the output
        to your needs.

        I can see two methods. One uses the document.getEle mentsByTagName( "div")
        collection and finds the structure by checking which elements are inside
        each other. The other uses recursive descent on the tree. In both cases,
        I build a datastructure of nodes on the form
        node ::= {elem: DivNode, children: [array of divs nested inside DivNode]}

        Using div collection, assuming that the divs are in the order the
        start tags occour in the document (as I believe they should be):
        ---
        // function that checks whether node2 is a predecessor of node1
        function parentOf(node1, node2) {
        while(node1!=nu ll) {
        if (node1 == node2) {return true;}
        node1 = node1.parentNod e;
        }
        return false;
        }

        function findDivsNest(el em) {
        var divs = elem.getElement sByTagName("div ");
        var stack = [];
        var topNode = {elem:elem,chil dren:[]};
        var currentNode = topNode;
        for (var i = 0; i<divs.length;i ++) {
        var div = divs[i];
        while (!parentOf(div, currentNode.ele m)) {
        currentNode = stack.pop();
        }
        var thisNode = {elem:div,child ren:[]};
        currentNode.chi ldren.push(this Node);
        stack.push(curr entNode);
        currentNode = thisNode;
        }
        return topNode.childre n;
        }
        ---

        Recursive descent version:
        ---
        function findDivsRec(nod e) {
        if (node.nodeType != 1 && node.nodeType != 9) {
        return []; // non-element, non-document node
        }
        var divs = [];
        for (var chld = node.firstChild ; chld != null; chld=chld.nextS ibling) {
        divs = divs.concat(fin dDivsRec(chld)) ;
        }
        if (/^div$/i.test(node.tag Name)) {
        return [{elem:node,chil dren:divs}];
        } else {
        return divs;
        }
        }
        ---

        An example of how to output the data as text:
        ---
        function divsToLines(div s,indent) {
        indent = indent || "";
        var nextIndent;
        var result = [];
        for (var i=0;i<divs.leng th;i++) {
        var div=divs[i];
        if (div.children.l ength > 0) {
        nextIndent = nextIndent || indent + " "; // calc once
        result.push(ind ent+" + <div id=\""+div.elem .id+"\">");
        result = result.concat(d ivsToLines(div. children,nextIn dent));
        result.push(ind ent+" <\/div>");
        } else {
        result.push(ind ent+" - <div id=\""+div.elem .id+"\"><\/div>");
        }
        }
        return result;
        }

        function divsToString(di vs) {
        return divsToLines(div s).join("\n");
        }
        ---

        You can then test it with

        alert(divsToStr ing(findDivsRec (document)));
        or
        alert(divsToStr ing(findDivsNes t(document)));

        If you want the output to be HTML, it's easy to fix.
        /L
        --
        Lasse Reichstein Nielsen - lrn@hotpop.com
        DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleD OM.html>
        'Faith without judgement merely degrades the spirit divine.'

        Comment

        • Phil

          #5
          Re: Recursive function : driving me crazy...

          Thank you. Have to study your code...it's a hard one for me :-)


          "Lasse Reichstein Nielsen" <lrn@hotpop.com > a écrit dans le message de news:
          hdznipu3.fsf@ho tpop.com...[color=blue]
          > "Phil" <pasdemail@pasd email.com> writes:
          >[color=green]
          > > Thanks for your example, but I can already made this. What I want is[/color][/color]
          really[color=blue][color=green]
          > > displaying (document.write ) the tree, with nodes, children and so forth
          > > (Missing closing tags is not the point, I write this on the fly and I[/color][/color]
          know[color=blue][color=green]
          > > they are missing)[/color]
          >
          > I'll just write it as a string here, I'm sure you can convert the output
          > to your needs.[/color]


          Comment

          • McKirahan

            #6
            Re: Recursive function : driving me crazy...

            "Phil" <pasdemail@pasd email.com> wrote in message
            news:_9KdnYBXEa lu3nGiRVn-uA@giganews.com ...[color=blue]
            >[color=green]
            > > I may not understand your problem.
            > >
            > > You say that you are "trying to display all DIV tags of a document" and[/color]
            > that[color=green]
            > > you "can retrieve all DIV using getElementsByTa gName"; what does it[/color][/color]
            matter[color=blue][color=green]
            > > how deep they are nested?
            > >
            > > Below is a page that displays the id's of all <DIV> tags. Watch for
            > > word-wrap.
            > >[/color]
            >
            > Thanks for your example, but I can already made this. What I want is[/color]
            really[color=blue]
            > displaying (document.write ) the tree, with nodes, children and so forth
            > (Missing closing tags is not the point, I write this on the fly and I know
            > they are missing)
            >
            > So if a div has children, I need to write the + sign, then the nested
            > children (if any) indented, etc
            > + <DIV id="2">
            > - <DIV id="2-1"></DIV>
            > + <DIV id="2-2"></DIV>
            > - <DIV id="2-2-1"></DIV>
            > - <DIV id="2-2-2"></DIV>
            > </DIV>[/color]


            Try this as-is; watch for word-wrap.
            It may not be that elegant but it works.


            <html>
            <head>
            <title>getElems .htm</title>
            </head>
            <body>

            <DIV id="1">
            <DIV id="1-1"></DIV>
            </DIV>
            <DIV id="2">
            <DIV id="2-1"></DIV>
            <DIV id="2-2">
            <DIV id="2-2-1"></DIV>
            <DIV id="2-2-2"></DIV>
            </DIV>
            </DIV>
            <DIV id="3"></DIV>

            <script language="javas cript" type="text/javascript">
            <!--
            var diva = new Array();
            var divi = 0;
            var divs = document.getEle mentsByTagName( "DIV");
            var save = "|";
            for (var i=0; i<divs.length; i++) {
            if (save.indexOf(" |"+divs[i].id+"|") < 0) {
            getElement(divs[i],0);
            }
            }
            function getElement(tag) {
            var tags = tag.getElements ByTagName("DIV" );
            if (tag.childNodes[0] != null) {
            save += tag.id + "|";
            divi++;
            diva[divi] = "+ " + tag.id;
            for (var j=0; j<tag.childNode s.length; j++) {
            getElement(tag. childNodes[j]);
            save += tag.childNodes[j].id + "|";
            }
            } else {
            divi++;
            diva[divi] = "- " + tag.id;
            }
            }
            var divx = "DIV tags:<br>";
            for (var x=1; x<diva.length; x++) {
            divx += "<br>" + diva[x];
            }
            document.write( "<pre>" + divx + "</pre>");
            // -->
            </script>
            </body>
            </html>


            Comment

            • Phil

              #7
              Re: Recursive function : driving me crazy...

              Thanks a lot. I let you know how things go

              "McKirahan" <News@McKirahan .com> a écrit dans le message de news:
              ODZGb.656303$HS 4.4674451@attbi _s01...[color=blue]
              > "Phil" <pasdemail@pasd email.com> wrote in message
              > news:_9KdnYBXEa lu3nGiRVn-uA@giganews.com ...[color=green]
              > >[/color][/color]


              Comment

              Working...