网站备案制作ip域名查询地址
vue中删除dom 节点
对于本系列简短功能介绍的第三篇文章,我想向您展示一个使用HTML DOM时必不可少的简单函数。 该函数称为clean()
,其目的是删除注释和纯空白文本节点。
该函数将单个元素引用作为其参数,并从其中删除所有那些不需要的节点。 该函数直接在所讨论的元素上操作,因为JavaScript中的对象是通过引用传递的 -这意味着该函数接收的是对原始对象的引用,而不是其副本。 这是clean()
函数的代码:
function clean(node)
{
for(var n = 0; n < node.childNodes.length; n ++)
{
var child = node.childNodes[n];
if
(
child.nodeType === 8
||
(child.nodeType === 3 && !/\S/.test(child.nodeValue))
)
{
node.removeChild(child);
n --;
}
else if(child.nodeType === 1)
{
clean(child);
}
}
}
因此,要从<body>
元素内部清除那些不需要的节点,只需执行以下操作:
clean(document.body);
或者,要清理整个文档,可以执行以下操作:
clean(document);
尽管通常的引用将是Element
节点,但它也可能是另一种包含元素的节点,例如#document
。 该功能也不限于使用HTML,还可以在任何其他类型的XML DOM上运行。
为什么要清理DOM
在JavaScript中使用DOM时,我们使用诸如firstChild
和nextSibling
类的标准属性来获取相对节点引用。 不幸的是,如以下示例所示,当DOM中存在空格时,可能会引起复杂性。
<div>
<h2>Shopping list</h2>
<ul>
<li>Washing-up liquid</li>
<li>Zinc nails</li>
<li>Hydrochloric acid</li>
</ul>
</div>
对于大多数现代浏览器(除了IE8和更早版本),先前HTML代码将导致以下DOM结构。
DIV
#text ("\n\t")
+ H2
| + #text ("Shopping list")
+ #text ("\n\t")
+ UL
| + #text ("\n\t\t")
| + LI
| | + #text ("Washing-up liquid")
| + #text ("\n\t\t")
| + LI
| | + #text ("Zinc nails")
| + #text ("\n\t\t")
| + LI
| | + #text ("Hydrochloric acid")
| + #text ("\n\t")
+ #text ("\n")
换行符和树内的制表符显示为空白#text
节点。 因此,例如,如果我们从对<h2>
元素的引用开始,则h2.nextSibling
将不会引用<ul>
元素。 相反,它将引用它前面的空白#text
节点(换行和制表符)。 或者,如果我们从对<ul>
元素的引用开始,那么ul.firstChild
将不是第一个<li>
,而是它之前的空白。
HTML注释也是节点,并且大多数浏览器也将它们保留在DOM中-应当将它们保存在DOM中,因为由浏览器来决定哪些节点重要而哪些节点不重要。 但是脚本实际上很少需要注释中的数据的情况很少。 注释(和中间的空格)很有可能是不需要的“垃圾”节点。
有几种处理这些节点的方法。 例如,通过遍历它们:
var ul = h2.nextSibling;
while(ul.nodeType !== 1)
{
ul = ul.nextSibling;
}
最简单,最实用的方法就是删除它们。 这就是clean()
函数的作用–有效地规范元素的子树,以创建与我们的实际使用相匹配的模型,并且在浏览器之间是相同的。
清除了原始示例中的<div>
元素后, h2.nextSibling
和ul.firstChild
引用将指向期望的元素。 清理后的DOM如下所示。
SECTION
+ H2
| + #text ("Shopping list")
+ UL
| + LI
| | + #text ("Washing-up liquid")
| + LI
| | + #text ("Zinc nails")
| + LI
| | + #text ("Hydrochloric acid")
功能如何运作
clean()
函数是递归的–一个可以自我调用的函数。 递归是一个非常强大的功能,意味着该功能可以清除任何大小和深度的子树。 递归行为的关键是if
语句的最终条件,下面将重复说明。
else if(child.nodeType === 1)
{
clean(child);
}
因此,每个元素的子代都传递给clean()
。 然后,该子节点的子节点传递给clean()
。 一直进行到所有后代都被清理干净为止。
在clean()
每次调用中,该函数都会循环访问元素的childNodes
集合,从而删除值除空白之外的任何#comment
节点( nodeType
为8)或#text
节点( nodeType
为3)。 正则表达式实际上是一个反向测试,查找不包含非空格字符的节点。
当然,该功能不会删除所有空格。 保留属于#text
节点(也包含非空白文本)的所有空白。 因此,仅受影响的#text
节点就是那些只有空白的节点。
请注意,迭代器必须每次都查询childeNodes.length
,而不是预先保存length
,这通常更有效。 之所以这样做,是因为我们要删除节点,这显然会更改集合的长度。
翻译自: https://www.sitepoint.com/removing-useless-nodes-from-the-dom/
vue中删除dom 节点