2012-06-06 47 views
7

沒有涉及太多細節,我正在使用javascript清理表格內部的空白。我需要刪除大量的文本節點。這似乎是我的腳本中涉及到IE9的瓶頸。從DOM中有效刪除文本節點

以下所有方法都可以完成這項工作,但會導致巨大的減速。

domNode.removeNode(true); 
domNode.nodeValue = ""; 
domNode.parentNode.removeChild(domNode); 

有沒有辦法做一個批量刪除或一種方法來隱藏他們在dom或這樣的。快一點。

我也試過這對textnodes:

domNode.innerHTML = ''; 

雖然它迅速執行,該textnodes似乎是由它矢志不渝。

此外,我需要保留事件綁定,因此整個表上的.innerHTML替換看起來並不是一個真正的選項。雖然它運行速度快了5倍。

更新: 上建議的解決方案粗糙基準:

//around 480ms 
stripWhitespaceTextNodes(domNode); 

//around 640ms 
parent.removeChild(domNode); 
stripWhitespaceTextNodes(domNode); 
parent.insertBefore(domNode, nextNode); 

//around 700ms 
tables[i].style.visibility = 'hidden'; 
stripWhitespaceTextNodes(domNode); 
tables[i].style.visibility = 'visible'; 

//around 1140ms 
tables[i].style.display = 'none'; 
stripWhitespaceTextNodes(domNode); 
tables[i].style.display = 'block'; 

這是在4桌進行具有1500行的一個表。

stripWhitespaceTextNodes()函數的關鍵是刪除文本節點,這似乎是瓶頸,這是我對它的各種嘗試。

domNode.parentNode.removeChild(domNode); 
domNode.removeNode(true); 
domNode.nodeValue = ""; // <-- CURRENTLY THIS ONE IS THE TOP RUNNER 
domNode.replaceWholeText(''); 
domNode.deleteData(0, domNode.length); 

var txtNode = document.createTextNode(""); 
domNode.parentNode.replaceChild(txtNode, domNode); 
parent.insertBefore(domNode, nextNode); 

//fast but doesn't work 
domNode.innerHTML = ''; 
+0

我會對細節感興趣。爲什麼你需要從表格中刪除whitespace-textNodes,它們不會影響顯示? – Bergi

+0

他們在IE9中做。有關這些詳細信息,請參閱此問題。 http://stackoverflow.com/questions/9895095/wanted-ie9-table-cell-ghost-alive-and-without-js至於爲什麼我無法修復它在服務器端,這是另一個長長的故事。 .. – Serhiy

+0

您是否嘗試過使用domNode.innerText =''或domNode.textContent =''來刪除文本節點? – tjscience

回答

0

你可以做到這一點的一種方法是克隆整個表並做「異地」操作。這意味着要對克隆不在DOM上的克隆執行操作。之後,用修改後的克隆替換整個表格。這樣,這些行動就不會陷入困境。

Here's an answer它引用了幾種「克隆」DOM併爲DOM之外的操作創建「容器元素」的方法。

+0

我可能跳過DOM重繪假設的槍。創建克隆的domNode並使用它不會更快。這似乎也許IE的domNode操作工具可能會很慢。 – Serhiy

6

通常的技巧是在進行大的更改之前從DOM中刪除您正在執行這些操作的容器,然後在完成後將其還原。

所以你的情況,這可能是:即使當樹被從頁面的DOM分離

var table = /* ...get a reference to the table...*/; 
var nextNode = table.nextSibling; // May be null, that's fine 
var parent = table.parentNode; 
parent.removeChild(table); 
/* ...clean up the text nodes... */ 
parent.insertBefore(table, nextNode); 

事件處理程序保持連接,所以他們會在那裏當樹被放回。

+0

如果你只是想防止重繪,'table.style.display =「none」'應該足夠了。 – Bergi

+0

@Bergi:與re *流*不同的是* *顏色。但是,是的,絕對的,OP應該儘量讓桌子不能顯示,並選擇最適合他/她的桌子。 –

+0

區別在哪裏?當然,當js使用css值進行計算時(不在這裏),可能會出現沒有重繪的迴流,但它們都不會發生隱藏的元素。 – Bergi

0

您可以嘗試從文檔中分離您的表格(表格DOM元素),在它上面移除並刪除空白文本節點,然後將表格插回到原始位置。在理論上你應該獲得速度 - 渲染樹不需要在每次傳遞時更新,這對於文檔中的表格是昂貴的。

+0

感謝您的建議,那是我在想什麼/希望。但是當我運行測試時,從DOM中刪除表的工作實際上變慢了。這沒有意義,但這是我得到的結果。 – Serhiy