通过DOM动态删除多个节点报错原因理解

通过DOM动态删除多个节点报错原因理解

在DOM中,我们可以通过removeChild( )来删除元素的子节点,但有时当我们通过循环函数删除一个元素的多个子节点时,浏览器却显示:
Failed to execute ‘removeChild’ on ‘Node’: parameter 1 is not of type ‘Node’.

这是什么原因呢?接下来分析几个可能常出现的错误写法.

<ul id = "UL">
		<li><input type="text"></li>
	</ul>
	<button id = "btn">添加</button>
	<button id = "delete">DELETE</button>
	<script>
		var ul = document.getElementById("UL");
        var btn = document.getElementById("btn");
        var Delete = document.getElementById("delete");
        btn.onclick = function(event)
        {
        	var li = document.createElement("li");
        	var input = document.createElement("input");
        	li.appendChild(input);
        	ul.appendChild(li);
        }
        Delete.onclick = function(event)
        {
        	//var count = ul.children.length;
        	//for(var i = 1;i<count;i++)
        	//	ul.removeChild(ul.children[i]);
        }
	</script>

我们写个简单的程序,1566288107.png

当我们点击 添加 按钮时,会动态添加一个新的 < li > 元素,当点击删除按钮时,会删除出第一个< li >元素外所有的< li >元素。
1.

 Delete.onclick = function(event)
        {
        	for(var i = 1;i<ul.children.length;i++)
            ul.removeChild(ul.children[i]);
        }

通过这种写法删除添加的子节点。结果是:
结果1.png
结果2.png

并没有完全删除,但浏览器没有报错
2.

 Delete.onclick = function(event)
        {
        	var count = ul.children.length;
        	for(var i = 1;i<count;i++)
        		ul.removeChild(ul.children[i]);
        }

通过这种方式,不仅删除不完全,浏览器还会报错。
报错1.png

  1. 正确方式 (方法不止一个)
Delete.onclick = function(event)
        { 	
         while(ul.children.length>=2)
         	ul.removeChild(ul.lastElementChild);
        }

当时用这种方式时,浏览器没有报错而且达成我们的要求,即完全删除所有动态添加的子节点。
完1.png
完2.png

前两种方法错误的原因我觉得只有一点:对DOM理解不深。
依次分析代码
1.

我们在循环函数判断条件那里写的是 ul.children.length ,即ul元素的子元素节点个数。 每当判断 i 的大小与 ul.children.length 的大小关系时,ul.children.length 都会发生一次更新。也就是说,ul.children.length 一直是动态变化的,当你添加一个子节点之后,他会动态加一,当你删除一个子节点时,他会动态减一。因此每当循环一次,ul.children.length的值就会减一。因此,当 i 的值大于等于 ul.children.length的值时,循环就停了。至于删除不完全是因为,每次删除后,ul.children[ i ] 的值就变成了删除前的ul.children[ i + 1 ], 可以简单理解为 ” 补位“, 前面一个走了,原来它后面的就占了它的位子。

 Delete.onclick = function(event)
        {
        	
         // while(ul.children.length>=2)
         // 	ul.removeChild(ul.lastElementChild);
         var count = ul.children.length;
        	for(var i = 1;i<count;i++)
        	{
        		ul.removeChild(ul.children[i]);
        		console.log(ul.children[i]);

        	}
                 }

分析1.png

打印出来ul的每个子节点,我们会发现控制台打印出来的结果中有一个 undefined 。原因和上面差不多,因为ul.children的长度是动态变化的,而count 记录的是初始时ul的子节点数,但随着ul子节点数量的减少以及 i 的增大,ul.children[i]会发生越界,因此打印出来的结果是undefined. 而removeChild()参数必须是一个节点才可以,否则会报错。
我觉得出现这样的错误是因为可能把ul.children当成静态数组了。如果我们删除数组中的元素,用这种方法完全没问题,但是这里的ul.children是动态的,因此要多加注意。

发布了32 篇原创文章 · 获赞 10 · 访问量 3423

猜你喜欢

转载自blog.csdn.net/shandamengcheng/article/details/99859110