为什么一次不能删除完?

来源:9-14 删除节点removeChild()

alias_neo3443231

2017-06-20 16:52

测试删除节点时,用了点ES6语法:


function clearText() {
  var content=document.getElementById("content");
  // 在此完成该函数
  var childs = content.childNodes;
  console.log(childs);
  for(child of childs){
  	content.removeChild(child);
  }
}

实际执行时诡异的事情出现了,点一次没反应,点两次消除三行,点三次消除剩下的两行....

于是我用console.log把子节点列表返回到控制台,

结果发现是一个长度11的数组,再然后特么这个数组对象居然还有五个字面量属性,控制台输出如下:

[text, h1, text, h1, text, h1, text, h1, text, h1, text]
0:h1
1:h1
2:h1
3:h1
4:h1
length:5
__proto__:NodeList

说明第一次删除了所有的text,第二次部分删除了h1,第三次删干净了...

可是我在for循环中,console.log(child)得到了全部的节点列表。。。为啥不能一次删完?

[text, h1, text, h1, text, h1, text, h1, text, h1, text]
#text
<h1>html</h1>
#text
<h1>php</h1>
text
<h1>javascript</h1>
#text
<h1>jquery</h1>
#text
<h1>java</h1>
#text


写回答 关注

2回答

  • 慕无忌8527878
    2017-08-07 13:52:25

    不知道我这样写有没有什么问题,如果你能发现问题的话请告诉我一下哈,谢谢!

    <script type="text/javascript">
    function clearText() {
      var content=document.getElementById("content");
      // 在此完成该函数
      var x = content.children;
      for(let i = x.length - 1 ;i >=0 ;i--){
          content.removeChild(x[i]);
      }
      
    }
    </script>


  • alias_neo3443231
    2017-06-21 09:35:02

    我已经搞懂了,自问自答,也算做个记录,并给后来学习的猿友提供点经验。

    function clearText() {
      var content=document.getElementById("content");
      // 在此完成该函数
      var childs = content.childNodes;
      console.log(childs);
      for(child of childs){
          content.removeChild(child);
      }
    }

    这段函数的问题在于,for of循环中,of后面跟的变量长度始终在变化,所以递归无法得到正确结果。

    那么很简单的方法是直接获取childs长度然后进行for循环,然而存在浏览器兼容性问题,因为列表长度不一致。

    于是换个思路,如果我把取到的childNode存起来呢?这样:

    function clearText() {
      let content=document.getElementById("content");
      let childs = content.childNodes;
      let buffers = childs;
      // 在此完成该函数
      for(let buffer of buffers){
      	content.removeChild(buffer);
      }
    }

    运行结果没有变化,可见childNodes存储的是一个指针列表,buffer指向的对象依然是原始目标,导致content的删除子节点影响buffers存储空间。

    那好,再变...

    function clearText() {
      let content=document.getElementById("content");
      let childs = content.childNodes;
      let buffers = Array.from(childs);
      // 在此完成该函数
      for(let buffer of buffers){
      	content.removeChild(buffer);
      }
    }

    这次运用了一个Array.from函数,这是es6新增函数,将对象存成数组。

    这次buffers彻底变成了数组,console.log可以看到,原型不再是NodeList而是Array。

    于是通关....

    发现我js基础不是一般的差>_<。泪

JavaScript进阶篇

本课程从如何插入JS代码开始,带您进入网页动态交互世界

468061 学习 · 21891 问题

查看课程

相似问题