Get text content of a div with YAHOO Dom.getFirstChild(div)?

Discussion in 'Javascript' started by david.karr, May 19, 2008.

  1. david.karr

    david.karr Guest

    I have a simple test page with a "div" that just contains text
    content. I assigned a var to the "div" element, and I'm trying to get
    the "first child" of that element to get the text content. I'm
    stepping through the code in firebug, and the var pointing to the div
    looks correct, and it even shows the "firstChild" is my text content.
    However, when I execute the line to get the first child, the result is
    null.

    I'm using YUI for this, but I doubt I'm making a YUI-specific mistake.

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/
    TR/html4/strict.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /
    >

    <title>Text Content Problem</title>
    <script type="text/javascript" src="yui/yahoo-dom-event/yahoo-
    dom-event.js"></script>
    <script type="text/javascript" src="yui/element/element-beta-
    min.js"></script>
    </head>
    <body>
    <div id="textdiv">
    This is some text.
    </div>
    <script type="text/javascript">
    YAHOO.util.Event.onDOMReady(function()
    {
    var textdiv = document.getElementById("textdiv");
    var textcontent =
    YAHOO.util.Dom.getFirstChild(textdiv);
    alert(textcontent);
    });
    </script>
    </body>
    </html>
    david.karr, May 19, 2008
    #1
    1. Advertising

  2. david.karr

    david.karr Guest

    I got this working by reading the "innerHTML" attribute. Is there a
    better way to do this?

    On May 19, 1:27 pm, "david.karr" <> wrote:
    > I have a simple test page with a "div" that just contains text
    > content. I assigned a var to the "div" element, and I'm trying to get
    > the "first child" of that element to get the text content. I'm
    > stepping through the code in firebug, and the var pointing to the div
    > looks correct, and it even shows the "firstChild" is my text content.
    > However, when I execute the line to get the first child, the result is
    > null.
    >
    > I'm using YUI for this, but I doubt I'm making a YUI-specific mistake.
    >
    > <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/
    > TR/html4/strict.dtd">
    > <html>
    > <head>
    > <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /
    >
    > <title>Text Content Problem</title>
    > <script type="text/javascript" src="yui/yahoo-dom-event/yahoo-
    > dom-event.js"></script>
    > <script type="text/javascript" src="yui/element/element-beta-
    > min.js"></script>
    > </head>
    > <body>
    > <div id="textdiv">
    > This is some text.
    > </div>
    > <script type="text/javascript">
    > YAHOO.util.Event.onDOMReady(function()
    > {
    > var textdiv = document.getElementById("textdiv");
    > var textcontent =
    > YAHOO.util.Dom.getFirstChild(textdiv);
    > alert(textcontent);
    > });
    > </script>
    > </body>
    > </html>
    david.karr, May 19, 2008
    #2
    1. Advertising

  3. david.karr

    RobG Guest

    On May 20, 8:04 am, "david.karr" <> wrote:
    > I got this working by reading the "innerHTML" attribute. Is there a
    > better way to do this?


    That depends on how you rate "better". If you know that the element
    will only ever contain plain text, innerHTML is a good cross-browser
    way of doing it.

    In a more general case, you should use the DOM 3 Core textContent
    property. However, since not all browsers support it, you need to
    have a couple of alternatives also such as innerText for those that
    support it and, when all else fails, recurse over child nodes getting
    their text nodes and grabbing the content.

    e.g.

    function getText(el)
    {
    if (typeof el == 'string') el = document.getElementById(el);

    // Try DOM 3 textContent property first
    if (typeof el.textContent == 'string') {return el.textContent;}

    // Try MS innerText property
    if (typeof el.innerText == 'string') {return el.innerText;}

    // Finally, recurse over child nodes
    return rec(el);

    // Recursion function
    function rec(el) {
    var n, x = el.childNodes;
    var txt = '';
    for (var i=0, len=x.length; i<len; ++i){
    n = x;
    if (3 == n.nodeType) {
    txt += n.data;
    } else if (1 == n.nodeType){
    txt += rec(n);
    }
    }
    return txt.replace(/\s+/g,' ');
    }
    }



    --
    Rob
    RobG, May 20, 2008
    #3
  4. david.karr

    GTalbot Guest

    On 19 mai, 19:05, RobG <> wrote:
    > On May 20, 8:04 am, "david.karr" <> wrote:


    > In a more general case, you should use the DOM 3 Core textContent
    > property.


    Agreed.

    > However, since not all browsers support it,


    Internet Explorer 8 final will not support DOM 3 Core textContent. The
    bug requesting support for it was closed.

    > you need to
    > have a couple of alternatives also such as innerText for those that
    > support it and, when all else fails, recurse over child nodes getting
    > their text nodes and grabbing the content.
    >
    > e.g.
    >
    > function getText(el)
    > {
    > if (typeof el == 'string') el = document.getElementById(el);
    >
    > // Try DOM 3 textContent property first
    > if (typeof el.textContent == 'string') {return el.textContent;}
    >
    > // Try MS innerText property
    > if (typeof el.innerText == 'string') {return el.innerText;}
    >
    > // Finally, recurse over child nodes
    > return rec(el);
    >
    > // Recursion function
    > function rec(el) {
    > var n, x = el.childNodes;
    > var txt = '';
    > for (var i=0, len=x.length; i<len; ++i){
    > n = x;



    One question for you, Rob. Just one. The first iteration will perform

    n = x[1];
    and will not perform
    n = x[0];
    due to pre-incrementation (++i).

    What makes you think or assume that the first node can be
    overstepped? ... unless I'm missing something here..


    > if (3 == n.nodeType) {
    > txt += n.data;
    > } else if (1 == n.nodeType){


    A side note. Internet Explorer 8 will not support enumeration of
    nodeType constant values: idem est, the following is perfectly doable
    in other browsers (and a more self-explanatory, easier to review,
    understand, maintain than memorizing digits)

    } else if(n.ELEMENT_NODE == n.nodeType){

    Regards, GĂ©rard
    GTalbot, May 23, 2008
    #4
  5. david.karr

    RobG Guest

    On May 23, 1:59 pm, GTalbot <> wrote:
    > On 19 mai, 19:05, RobG <> wrote:
    >
    > > On May 20, 8:04 am, "david.karr" <> wrote:
    > > In a more general case, you should use the DOM 3 Core textContent
    > > property.

    >
    > Agreed.
    >
    > > However, since not all browsers support it,

    >
    > Internet Explorer 8 final will not support DOM 3 Core textContent. The
    > bug requesting support for it was closed.


    To me, a bug is a different animal to an enhancement or change. But
    if they want to call requests for enhancements bugs, so be it. :)

    > > you need to
    > > have a couple of alternatives also such as innerText for those that
    > > support it and, when all else fails, recurse over child nodes getting
    > > their text nodes and grabbing the content.

    >
    > > e.g.

    >
    > > function getText(el)
    > > {
    > > if (typeof el == 'string') el = document.getElementById(el);

    >
    > > // Try DOM 3 textContent property first
    > > if (typeof el.textContent == 'string') {return el.textContent;}

    >
    > > // Try MS innerText property
    > > if (typeof el.innerText == 'string') {return el.innerText;}

    >
    > > // Finally, recurse over child nodes
    > > return rec(el);

    >
    > > // Recursion function
    > > function rec(el) {
    > > var n, x = el.childNodes;
    > > var txt = '';
    > > for (var i=0, len=x.length; i<len; ++i){
    > > n = x;

    >
    > One question for you, Rob. Just one. The first iteration will perform
    >
    > n = x[1];


    No it wont - perhaps you've been working in a different language
    lately? :)


    > and will not perform
    > n = x[0];


    Yes it will.


    > due to pre-incrementation (++i).


    The increment happens at the end of the loop, not the start:

    ECMAScript ed 3, Section 12.6.3 (I hope my re-formatting is OK):

    The production IterationStatement :
    for ( var VariableDeclarationListNoIn ;
    Expression(opt) ;
    Expression(opt) )
    Statement

    is evaluated as follows:

    1. Evaluate VariableDeclarationListNoIn.
    2. Let V = empty.
    3. If the first Expression is not present, go to step 8.
    4. Evaluate the first Expression.
    5. Call GetValue(Result(4)).
    6. Call ToBoolean(Result(5)).
    7. If Result(6) is false, go to step 14.
    8. Evaluate Statement.
    9. If Result(8).value is not empty, let V = Result(8).value.
    10. If Result(8).type is break and Result(8).target is in the current
    label set, go to step 17.
    11. If Result(8).type is continue and Result(8).target is in the
    current label set, go to step 13.
    12. If Result(8) is an abrupt completion, return Result(8).
    13. If the second Expression is not present, go to step 3.
    14. Evaluate the second Expression.
    15. Call GetValue(Result(14)). (This value is not used.)
    16. Go to step 3.
    17. Return (normal, V, empty).


    So the second expression is not evaluated until step 14, which is
    after the statement (step 8). When ++i is evaluated, the post/prefix
    operator only has consequences inside the statement. By the time the
    next statement is processed, i will be incremented. Therefore it
    doesn't matter whether ++i or i++ is used.

    While it might be clearer if i++ is used, it makes no difference in
    practice.

    > What makes you think or assume that the first node can be
    > overstepped? ... unless I'm missing something here..


    Yep. :)

    >
    > > if (3 == n.nodeType) {
    > > txt += n.data;
    > > } else if (1 == n.nodeType){

    >
    > A side note. Internet Explorer 8 will not support enumeration of
    > nodeType constant values:


    Is any reason given? nodeType is in the DOM 2 Core specification (and
    DOM 3, but that is likely irrelevant for IE for some time yet):

    <URL: http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-111237558 >

    > idem est, the following is perfectly doable
    > in other browsers (and a more self-explanatory, easier to review,
    > understand, maintain than memorizing digits)
    >
    > } else if(n.ELEMENT_NODE == n.nodeType){


    That would require a bit of testing to ensure those browsers that get
    to the recursive function (I don't know of any in use but I'm sure
    there are some) are sufficiently standards compliant for it to work.
    I remember implementing the recursive function some time ago because I
    had some old browsers that needed it (the other alternative is
    innerHTML and a tag-stripping RegExp, which I didn't like), I'd have
    to find one again.

    If needed, the function could look at the value returned by n.nodeType
    and make a choice of whether the comparison needs ELEMENT_NODE et al
    or a number. Overkill?


    --
    Rob
    RobG, May 23, 2008
    #5
    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. checoo
    Replies:
    0
    Views:
    547
    checoo
    Dec 25, 2006
  2. checoo
    Replies:
    1
    Views:
    512
  3. M Wells
    Replies:
    0
    Views:
    137
    M Wells
    Oct 6, 2004
  4. zhonghua

    about "var yahoo = window.yahoo || {}"

    zhonghua, Jul 10, 2006, in forum: Javascript
    Replies:
    2
    Views:
    119
    zhonghua
    Jul 10, 2006
  5. visu
    Replies:
    4
    Views:
    291
Loading...

Share This Page