2010-01-07 32 views
5

Tôi đang thực hiện một số thao tác của TextNodes trong javascript, và tôi (không may) cần hỗ trợ IE6. Node.normalize() đang bị lỗi và tôi cần giải quyết vấn đề này. Độ nghiêng đầu tiên của tôi là chỉ thực hiện lại nó bằng các phương thức DOM khác. Làm thế nào tôi sẽ thực hiện điều này?Node.normalize() treo trong IE6

+1

1 cho '(không may)' – SLaks

Trả lời

8

Phiên bản Sau đây là ngắn hơn và hiệu quả hơn so với những người khác được đăng ở đây. Những cải tiến bao gồm:

  • Không cuộc gọi lặp đi lặp lại để node.childNodesnode.childNodes.length
  • Không tạo ra các nút văn bản thêm; thay vào đó, đối với mỗi hợp nhất, giữ nút văn bản hiện đầu tiên và sử dụng phương pháp appendData()
  • ngắn

Mã:

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

Bạn cần phải xem xét đệ quy tất cả các nút con của nút hiện tại. Khi xem xét một nút, bạn sẽ xóa bất kỳ nút văn bản trống nào và kết hợp bất kỳ nút văn bản liền kề nào.

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

mã giả tốt. bạn có thể dịch nó sang javascript không? –

0

dựa trên giả tvanfosson của, đây là những gì tôi đã đưa ra trong 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

Tôi thực sự ghét chấp nhận câu trả lời của riêng tôi, nhưng tôi đã phụ thuộc rất nhiều vào tvanfosson để đưa ra điều này, và tôi đã bình chọn anh ấy. –

5

Các giải pháp trên đã chạy rất chậm và đâm Firefox cho tôi. Vì vậy, tôi đã tối ưu hóa nó một chút và nó hoạt động tốt ngay bây giờ (vấn đề chính là liên tục tham chiếu đến đối tượng bộ sưu tập HTML node.childNodes).

Cảm ơn các điểm khởi đầu tuyệt vời, nhưng tôi figured này là giá trị niêm yết:


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

Tôi nghĩ rằng giải pháp cung cấp ở trên là không hoàn toàn chính xác. FWIW, đây là một chức năng bình thường hóa làm việc cộng với một hàm keo mà sử dụng bình thường hóa bản địa nếu nó có sẵn:

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

Nhận xét về câu trả lời của tôi sẽ hữu ích nếu nó không chính xác. Ngoài ra, những gì bạn đã thực sự sửa chữa? –