2010-01-07 33 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