2010-01-07 51 views
5

我正在做一些JavaScript中的TextNodes操作,并且我(不幸)需要支持IE6。 Node.normalize()崩溃了,我需要解决这个问题。我的第一个倾向是用其他DOM方法重新实现它。我将如何实现这一点?在IE6 Node.normalize()崩溃

+1

+1'(不幸)' – SLaks 2010-01-07 20:04:48

回答

8

以下版本更短,效率比别人张贴在这里。这些改进包括:

  • 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

您需要递归查看当前节点的所有子节点。在考虑节点时,您可以删除任何空的文本节点并组合任何相邻的文本节点。

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 
+0

好的伪代码。你能不能把它翻译成JavaScript? – 2010-01-07 20:16:16

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; 
    } 
} 
+0

我真的很讨厌接受我自己的回答,但我确实非常依赖tvanfosson来提出这个问题,而且我已经投票给他了。 – 2010-01-19 20:00:03

5

在溶液上方运行相当缓慢,崩溃的Firefox我。所以我优化了一下,现在它工作得很好(主要问题是反复引用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--; 
    } 
} 
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); 

}

+0

如果答案不正确,我对答案的评论会有帮助。另外,你真正纠正了什么? – 2013-10-22 15:49:14