I am doing some manipulation of TextNodes in javascript, and I (unfortunately) need to support IE6. Node.normalize() is crashing, and I need to work around this. My first inclination is to just re-implement it using other DOM methods. How would I implement this?
+1
A:
You'd need to recursively look through all of the child nodes of the current node. When considering a node, you'd delete any empty text nodes and combine any adjacent text nodes.
function myNormalize( node )
for each child node of node do
if child is not text
normalize(child)
else
if child node is empty
delete
continue
else
sibling = next node
while sibling exists and sibling is a text node
if sibling is empty
delete sibling
else
combine sibling with child
get next sibling
end
end
end
end
end
tvanfosson
2010-01-07 20:09:16
good pseudocode. could you also translate it to javascript?
Christian Oudard
2010-01-07 20:16:16
A:
based on tvanfosson's pseudocode, here's what I came up with in javascript:
var ELEMENT_NODE = 1;
var TEXT_NODE = 3;
function normalize(node) {
for (i=0; i<node.childNodes.length; i++) {
var child = node.childNodes[i];
if (child.nodeType == ELEMENT_NODE) {
normalize(child);
continue;
}
if (child.nodeType != TEXT_NODE) { continue; }
var next = child.nextSibling;
if (next == null || next.nodeType != TEXT_NODE) { continue; }
var combined_text = child.nodeValue + next.nodeValue;
new_node = node.ownerDocument.createTextNode(combined_text);
node.insertBefore(new_node, child);
node.removeChild(child);
node.removeChild(next);
i -= 1;
}
}
Christian Oudard
2010-01-07 20:35:41
I really hate to accept my own answer, but I did rely heavily on tvanfosson to come up with this, and I've already voted him up.
Christian Oudard
2010-01-19 20:00:03
A:
The solution above was running very slow and crashing Firefox for me. So I optimized it a bit and it's working great now (the main issue was with repeatedly referencing the HTML collection object node.childNodes).
Thanks for the great starting point, but I figured this was worth posting:
function myNormalize(node) {
for (var i=0, children = node.childNodes, nodeCount = children.length; i<nodeCount; i++) {
var child = children[i];
if (child.nodeType == 1) {
myNormalize(child);
continue;
}
if (child.nodeType != 3) { continue; }
var next = child.nextSibling;
if (next == null || next.nodeType != 3) { continue; }
var combined_text = child.nodeValue + next.nodeValue;
new_node = node.ownerDocument.createTextNode(combined_text);
node.insertBefore(new_node, child);
node.removeChild(child);
node.removeChild(next);
i--;
nodeCount--;
}
}
Jon Raasch
2010-09-20 20:04:22