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

D

david.karr

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>
<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>
 
D

david.karr

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

RobG

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,' ');
}
}
 
G

GTalbot

On May 20, 8:04 am, "david.karr" <[email protected]> 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
 
R

RobG

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.

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. :)
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):

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?
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,260
Messages
2,571,038
Members
48,768
Latest member
first4landlord

Latest Threads

Top