从DOM中有效地删除文本节点

时间:2012-06-06 08:30:17

标签: javascript dom

没有太多细节,我正在使用javascript清理表格内的空白。我需要删除大量的文本节点。对于IE9来说,这似乎是我脚本的瓶颈。

以下所有方法都可以完成这项工作,但它们会导致极大的减速。

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

有没有办法进行批量删除或在dom中隐藏它们的方法。只是更快的东西。

我也在textnodes上试过这个:

domNode.innerHTML = '';

当它快速执行时,文本节点似乎没有被它发送。

另外,我需要保留事件绑定,因此整个表上的.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 = '';

3 个答案:

答案 0 :(得分:6)

通常的做法是在进行大的更改之前从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);

即使树与页面的DOM分离,事件处理程序仍保持连接状态,因此当树被放回时它们将存在。

答案 1 :(得分:0)

你可以做到的一种方法是克隆整个表并“非现场”进行操作。这意味着对克隆不在DOM上的克隆进行操作。然后,使用修改后的克隆单个替换整个表。这样,操作就不会陷入困境。

Here's an answer指的是“克隆”DOM并为DOM之外的操作创建“容器元素”的几种方法。

答案 2 :(得分:0)

您可以尝试从文档中分离表(表DOM元素),遍历它并删除空白文本节点,然后将表插回到原始位置。在理论上你应该获得速度 - 渲染树不需要在每次传递时更新,这对于文档中的表来说是昂贵的。