我正在javascript中对TextNodes进行一些操作,我(不幸的是)需要支持IE6。 Node.normalize()崩溃了,我需要解决这个问题。我的第一个倾向是使用其他DOM方法重新实现它。我该如何实现呢?
答案 0 :(得分:7)
以下版本比此处发布的版本更短,效率更高。改进是:
node.childNodes
和node.childNodes.length
appendData()
方法代码:
function normalize(node) {
var child = node.firstChild, nextChild;
while (child) {
if (child.nodeType == 3) {
while ((nextChild = child.nextSibling) && nextChild.nodeType == 3) {
child.appendData(nextChild.data);
node.removeChild(nextChild);
}
} else {
normalize(child);
}
child = child.nextSibling;
}
}
答案 1 :(得分:5)
上面的解决方案运行速度非常慢,并且让我崩溃了。所以我对它进行了优化,现在它工作得很好(主要问题是重复引用HTML集合对象node.childNodes)。
感谢您的出发点,但我认为这值得张贴:
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--;
}
}
答案 2 :(得分:1)
您需要以递归方式查看当前节点的所有子节点。在考虑节点时,您将删除任何空文本节点并组合任何相邻的文本节点。
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
答案 3 :(得分:0)
基于tvanfosson的伪代码,这是我在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;
}
}
答案 4 :(得分:0)
我认为上面提供的解决方案并不完全正确。 FWIW,这是一个工作规范化函数加上一个胶合函数,如果它可用,它使用原生规范化:
function _myNormalizeNode(node) {
if (! node) {
return;
}
var ELEMENT_NODE = 1;
var TEXT_NODE = 3;
var child = node.firstChild;
while (child) {
if (child.nodeType == ELEMENT_NODE) {
this._myNormalizeNode(child);
}
else if (child.nodeType == TEXT_NODE) {
var next;
while ((next = child.nextSibling) && next.nodeType == TEXT_NODE) {
var value = next.nodeValue;
if (value != null && value.length) {
child.nodeValue = child.nodeValue + value;
}
node.removeChild(next);
}
}
child = child.nextSibling;
}
}
function _normalizeNode(node) {
if (! node) {
return;
}
if (typeof node.normalize == "function") {
return node.normalize();
}
return _myNormalizeNode(node);
}