Node.normalize()在IE6中崩溃

时间:2010-01-07 20:01:59

标签: javascript dom internet-explorer-6

我正在javascript中对TextNodes进行一些操作,我(不幸的是)需要支持IE6。 Node.normalize()崩溃了,我需要解决这个问题。我的第一个倾向是使用其他DOM方法重新实现它。我该如何实现呢?

5 个答案:

答案 0 :(得分:7)

以下版本比此处发布的版本更短,效率更高。改进是:

  • 没有重复拨打node.childNodesnode.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);

}