【20180723】关于遍历并全部删除节点removeChild()循环方法的一点思考

Mooc JS进阶9-14课程任务

http://www.imooc.com/code/1700

试一试,定义clearText()函数,完成节点内容的删除。

1. 删除该节点的内容,先要获取子节点。

2. 然后使用循环遍历每个子节点。

3. 使用removeChild()删除节点。

代码三种方法如下:

<!DOCTYPE HTML>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

<title>无标题文档</title>

</head>



<body>

<div id="content">

  <h1>html</h1>

  <h1>php</h1>

  <h1>javascript</h1>

  <h1>jquery</h1>

  <h1>java</h1>

</div>



<script type="text/javascript">

function clearText() {

  var content=document.getElementById("content");

  // 在此完成该函数

  

  //法一,一次性清除节点内容

  for(var i=0;i<content.childNodes.length;i++){

      if(content.childNodes[i].nodeType!=1){   

         continue;  

      }else{

         content.removeChild(content.childNodes[i]);    

      }

         

      }



  //法二,一次性清除节点内容

/*   

   for(var i=content.childNodes.length-1;i>=0;i--){

      var chnode=content.childNodes[i];

      content.removeChild(chnode);  

   }

*/



  //法三,多次方清除节点内容

/*

   for(var i=0;i<content.childNodes.length;i++){

    var chnode=content.childNodes[i];

    content.removeChild(chnode);  

  }

*/

  

  }

  



</script>



<button onclick="clearText()">清除节点内容</button>







</body>

</html>

其实我开始没有想到这么多方法,这个是一个高赞的同学代码的回答。试着跑了一遍,跑到法3的时候,发现了一个很有趣的现象。

第一次点击,无效;第二次点击,清除奇数排序的三个节点;第三次点击,去一个节点,第四次点击,也是去一个节点。

通过四次点击完成节点清除。

看代码,没琢磨出个所以然。尝试console,虽然不是什么难问题,但是记录下这个问题的解决思路。算是给自己的思考做一个小小的总结吧。

调试程序和结果如示,主要是想明白需要观察哪些东西。

<!DOCTYPE HTML>

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

<title>无标题文档</title>

</head>



<body>

<div id="content">

  <h1>html</h1>

  <h1>php</h1>

  <h1>javascript</h1>

  <h1>jquery</h1>

  <h1>java</h1>

</div>



<script type="text/javascript">

function clearText() {

  var content=document.getElementById("content");

  console.log(content.childNodes);

  console.log(content.childNodes.length);

  //方法三,第一下没反应,没反应,按第二次会删除三个节点,然后再按就变成一个一个删

  // if you remove one node, the index will change, that means sequential index

  // point to odd index in original index;

  // and in div "content", there 11 nodes

  // [text, h1, text, h1, text, h1, text, h1, text, h1, text]

  // so first time , remove actione just remove "text"

  // second time, [h1, h1, h1, h1, h1], just remove html, javascript, java

  for (var i = 0; i < content.childNodes.length; i++) {

      var chnode = content.childNodes[i];

    console.log(i, chnode);

      content.removeChild(chnode);

  }



  // must remove child nodes from tail to head

  // for (var i = content.childNodes.length - 1; i >= 0; i--) {

  //     var chnode = content.childNodes[i];

  //    console.log(i, chnode);

  //    content.removeChild(chnode);

  //}



  

}

</script>



<button onclick="clearText()">清除节点内容</button>







</body>

</html>

可以看到,最开始是有11个节点,其实是因为缩进,算成了文本节点。

这段循环的问题在于,i=0 && i<length && i++,然后开始执行remove的时候,数组的长度是在变化的。

因此偶数位的节点会进位,恰好变成之前执行过的数位上。就是本来要执行0a,1b,2c,但是0a没了之后,变成了0b,1c,但是之前已经删过0,所以这次只删1c,不断执行下去,整个数组的每个偶数位节点在进位后恰好会避开本次删除。

因此看调试程序,最开始,是把空格删了。(假如把第一行的缩进空格删掉,让<h1>节点正好踩奇数位,其实都不会暴露这个问题。所以计算机的事情真是奇妙且阴差阳错啊。后面不断删奇数位,数组长度改变后,重复执行不断删新晋的奇数节点。

另外,IE低版本浏览器不认为空格是节点:)

假如不改for循环,仍然坚持自加的改法,也有两种

var length = content.childNodes.length;

// for (var i = 1; i <= length; i ++) {

//   var chnode = content.childNodes[length - i ];

//   content.removeChild(chnode);

//}



for (var i = 0; i < length; i++) {

    var chnode = content.childNodes[0];

    content.removeChild(chnode);

}

这里提供的两种方法

第一种其实就是从最后一个节点开始删除,(注意var i=1,不然循环第一步会对应第11个节点,在数组中只有0-10节点,第11个节点不属于数组,不可以remove child,走到这一步会报错,所以不能继续往下跑)

第二种是每次都删除数组的第一个,即使有数组迁移,每次都删除第一个或者最后一个,就不会有漏的了

问题不难,弄清楚挺有成就感的,勉励自己加油!

猜你喜欢

转载自blog.csdn.net/weixin_42767581/article/details/81490487