Reputation: 1566
Although I have read many posts on this subject, I am unable to get the desired result.
My goal is to get text of nested childnodes in pure JavaScript.
with this code
function GetChildNodes () {
var container = document.getElementById ("find");
for (var i = 0; i < container.childNodes.length; i++) {
var child = container.childNodes[i];
if (child.nodeType == 3) {
var str=child.nodeValue
console.log(str)
}
else {
if (child.nodeType == 1) {
var str=child.childNodes[0].nodeValue
console.log(str)
}
}
}
}
GetChildNodes()
I can get the text if html is
<div id="find">
aaa
<div>aaa</div>
<div>aaa</div>
<div>aaa</div>
<div>aaa</div>
</div>
But with html code like this
<div id="find">
aaa
<div>aaa<div>bbb</div></div>
<div>aaa<div>bbb</div></div>
<div>aaa</div>
<div>aaa</div>
</div>
...is wrong.
Could you please give me a solution?
Upvotes: 5
Views: 8791
Reputation: 3529
a short version of Paul's answer
function getText(node) {
if (node.nodeType == 3) return node.data; // text node
if (!node.childNodes) return '';
let s = '';
for (let i = 0; i < node.childNodes.length; i++) {
s += getText(node.childNodes[i]);
}
return s;
}
Upvotes: 0
Reputation: 1566
Since my purpose was also to change the text in nested elements if the text is equal to a string,
thanks to the advice of Paul S
I could solve my problem this way
<script type="text/javascript">
function GetChildNodes (container) {
function recursor(container){
for (var i = 0; i < container.childNodes.length; i++) {
var child = container.childNodes[i];
if(child.nodeType !== 3&&child.childNodes){
recursor(child);
}else{
var str=child.nodeValue;
if(str.indexOf('bbb')>-1){child.nodeValue='some other text'};
};
};
};
recursor(container);
};
var container = document.getElementById ("find");
GetChildNodes(container);
</script>
Thanks again Paul !
Upvotes: 2
Reputation: 66304
If you don't need to get the text node-by-node you can get all of it from the ancestor with node.textContent
,
var str = document.getElementById('find').textContent;
console.log(str);
Otherwise, you'll need to iterate or recurse through the DOM tree looking for nodeType 3
and accessing .data
or .childNodes
otherwise, e.g. recursing
function getText(node) {
function recursor(n) {
var i, a = [];
if (n.nodeType !== 3) {
if (n.childNodes)
for (i = 0; i < n.childNodes.length; ++i)
a = a.concat(recursor(n.childNodes[i]));
} else
a.push(n.data);
return a;
}
return recursor(node);
}
// then
console.log(getText(document.getElementById('find')));
Upvotes: 6
Reputation: 59232
It is because you're checking only for the childNodes
of find
, and not the childnodes of the childnodes and it goes on.
There is not limit of number of childs an element can have, and so you should have a for
loop every time or a recursive function.
Why don't you just do: document.getElementById('find').textContent;
?
Upvotes: 0