Reputation: 12616
OK, I have a little function walking the tree like this:
function walkTree(node, func, args) {
func(node, args);
node = node.firstChild;
while (node) {
walkTree(node, func, args);
node = node.nextSibling;
}
}
And another function that would pick up only the text nodes like so:
function selectTextNodes(node, nodes) {
if (node instanceof Text) {
nodes.push(node);
}
}
And finally, using both:
texts = [];
walkTree(body, selectTextNodes, texts);
However, it doesn't fill the list at all!
If I were to modify the test as to use Node.nodeType
it would work:
function selectTextNodes(node, nodes) {
if (node.nodeType == Node.TEXT_NODE) {
nodes.push(node);
}
}
On the other hand, in the console it works both ways:
t = window.document.createTextNode("test");
r = (t.nodeType == Node.TEXT_NODE) && (t instanceof Text);
That is, r is true.
Note that, all functions are nested inside another function that receives the body
variable. In my case, this is the contentDocument.body
of an iframe
. There is no x-domain restriction being applied.
Any idea what's going on?
Upvotes: 3
Views: 1628
Reputation: 664484
There are different Text
interfaces in the different windows. So, if you have a DOM node from your iframe document, it is not an instanceof window.Text
, but an instanceof iframe.contentWindow.Text
. Afaik, also the availability of the Text
interface as a Javascript object is non-standard.
That is why you just should check the nodeType
of the elements. But notice that (older?) IE does not support the TEXT_NODE
constant on Node
, so you will either need to compare with 3
or assign that value as a polyfill to Node.TEXT_NODE
.
Upvotes: 10
Reputation: 7452
<body>
<iframe name="ifr" id="ifr" src='test1.html'></iframe>
<button onclick="clkfn()">test</button>
<script>
function wrapper(body, iframeWindow) {
function walkTree(node, func, args) {
func(node, args);
node = node.firstChild;
while (node) {
walkTree(node, func, args);
node = node.nextSibling;
}
}
function selectTextNodes(node, nodes) {
if (node instanceof iframeWindow.Text) {
nodes.push(node);
}
}
texts = [];
walkTree(body, selectTextNodes, texts);
for (var i = 0; i < texts.length; i++) {
console.log("text #" + i + texts[i].nodeValue);
}
}
function clkfn() {
var ifr = frames["ifr"];
wrapper(ifr.document.body, ifr);
}
</script>
</body>
<!doctype html>
<html>
<head>
</head>
<body>
how are you?
I am fine. Thank you!
</body>
</html>
When you click on the button, console prints:
text #0 how are you? I am fine. Thank you!
Only change made to code is passed the iframe body and window. Then referred the Text object from iFrame window.
Upvotes: 1