ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Uncaught TypeError: Failed to execute appendChild on Node: parameter 1 is not of type Node 解决

2020-06-17 10:36:52  阅读:2091  来源: 互联网

标签:Node appendChild execute value 列表 window let document 节点


Uncaught TypeError: Failed to execute ‘appendChild’ on ‘Node’: parameter 1 is not of type ‘Node’ 报错原因分析及解决方案.

前序:

最近在复习一下js基础的时候,遇到一些小坑坑,虽然很快解决了但是还是久久不能平息我的小情绪,特来开贴填坑.在此想说的是,编写博客初心只是想记录自己遇到的一些问题,解决的一些思路及方案,等到用到的时候再回头看看,仅此而已,技术还未到家绝无指教之意。但也希望也能帮到某些遇到同样问题的小伙伴! 我坚信"一个人可以走得很快,两个人可以走得很远嘛!"
思维导图分析:

开始将字符串标签插入容器中程序报错原因是方法需要传入一个DOM节点的对象而不是字符串解决先创建虚拟节点此时虚拟节点是一个对象,再把数据与标签拼接插入最后用处理完成的虚拟节点插入页面中解决

兼容新手模式 博客代码举例演示尽量用最简单最接地气的例子 以大白话的方式解释原理

报错代码:

html:

  <input type="text" name="data" />
  <button class="console" onclick="addData()">点击把li到列表中</button>
  <ul class="list"></ul>

js:

    const input = window.document.getElementsByName("data")[0];
    function addData(){
      let value = input.value;
      let html = "<p>"+value+"</p>";
      window.document.getElementsByClassName("list")[0].appendChild(html)
    }

在这里插入图片描述
报错原因分析:

  • 出现这个报错的原因主要是传入appendChild()方法的参数不是一个有效的元素节点,而是字符串.
  • 可以通过nodeType()来检测节点的类型.方法返回结果如果为"1"的话,即是有效元素,是可以被添加进去的
    const p = window.document.createElement("p");//创建的虚拟节点 
    const p2 = "<p>"+value+"</p>";//字符串拼接
    console.log(p.nodeType); //返回值 "1" 有效的元素节点
    console.log(p2.nodeType); //返回值 "undefined" 无效的元素节点

解决方案1:
appendChild()方法必须传入一个有效的元素节点,调用createElement()方法创建一个虚拟节点,此时创建的虚拟节点是有效的元素节点,再把数据拼接完成,innerHTML插入到虚拟节点中,最后添加到列表中

    function addData() {
      let value = input.value;
      let li = window.document.createElement("li");
      li.innerHTML = "<p>" + value + "</p>";
      window.document.getElementsByClassName("list")[0].appendChild(li)
    }

解决方案2:

代码应该更优雅

    let html = new Array;
    function addData() {
      let value = input.value;
      let template = "<li><p>" + value + "</p></li>";
      html.push(template);
      window.document.getElementsByClassName("list")[0].innerHTML = html.join("");
    }

最后的效果是:
在这里插入图片描述
-----------------------------------------------拓展知识----------------------------------------------------
利用firstChild lastChild childNodes 现学现用,实现两个数据列表的点击数据交互(项目中表格比较多,下次用用看),我认为还是比较实用的,以后也许会用到呢,特来巩固一下,话不多说,demo敲起

html:

  <style>
    .boxStyle{
      border: 1px solid #000;display: inline-block; width: 50px;height: 50px;
    }
  </style>
  
<body>
  <button onclick="addBox()">单击将元素从列表二移动到列表一</button>
  <p>列表一:</p>
  <div id="BoxOne">
    <div class="boxStyle" style="background-color: pink;"></div>
  </div>
  <p>列表二:</p>
  <div id="BoxTwo">
    <div class="boxStyle" style="background-color: fuchsia;"></div>
    <div class="boxStyle" style="background-color: gold;"></div>
    <div class="boxStyle" style="background-color: red;"></div>
    <div class="boxStyle" style="background-color: royalblue;"></div>
    <div class="boxStyle" style="background-color: cyan;"></div>
  </div>
</body>

js:
兴致勃勃的写,结果上一个坑没填完,这回又掉进去了

  function addBox() {
  	
    const BoxOneChild = window.document.getElementById("BoxTwo").firstChild;
    console.log(BoxOneChild);           // #text 返回了文本节点????????emmmmmm
    //不敢相信的我又打印了其他三个节点属性
    console.log(BoxOneChild.nodeType);	// 3
    console.log(BoxOneChild.nodeName);  // #text
    console.log(BoxOneChild.nodeValue); // ""
    window.document.getElementById("BoxOne").children(BoxOneChild);
  }

打印结果图:
在这里插入图片描述
Why??? Who am I? Where I am?

立马求助了最帅的苏老师 原来:
在这里插入图片描述
于是我立即写下了解决方法 把div中所有的空格删除 再执行了打印
解决方法1:

<body>
  <button onclick="addBox()">单击将元素从列表二移动到列表一</button>
  <p>列表一:</p>
  <div id="BoxOne">
    <div class="boxStyle" style="background-color: pink;"></div>
  </div>
  <p>列表二:</p>
  <div id="BoxTwo"><div class="boxStyle" style="background-color: fuchsia;"></div><div class="boxStyle" style="background-color: gold;"></div><div class="boxStyle" style="background-color: red;"></div><div class="boxStyle" style="background-color: royalblue;"></div><div class="boxStyle" style="background-color: cyan;"></div></div>
</body>

结果:
在这里插入图片描述
作为一个有审美的前端工程师.怎么能让代码如此的不优雅呢?

  1. 书写规范的html格式代码利于项目维护.
  2. 现在倒是删除了div之间的空格 保不准哪天同事把代码格式化一下.那后果非常严重

于是我马不停蹄 立马写了一个筛选方法,上代码:
写在前面.这里有一个知识点,必须明白 element.childNodes 属性是直接返回节点的所有子节点的合集

  let nodeArr = new Array;
  (function () {
    let nodes = window.document.getElementById("BoxTwo").childNodes;
    for (i = 0; i < nodes.length; i++) {//遍历子节点集合
      if (nodes[i].nodeType === 1) {//筛选符合条件的节点 判断节点属性是否是 元素节点
        nodeArr.push(nodes[i])//添加到全局定义的数组中
      }
    }
  })()
  function addBox() {//点击执行
    if (nodeArr.length) {
      window.document.getElementById("BoxOne").appendChild(nodeArr[0]);
      nodeArr.splice(0, 1);
    } else {
      alert("列表二已经没有数据")
    }
  }

最终效果:
在这里插入图片描述
本文讲述的方法及属性汇总:
以下方法及熟悉所有浏览器支持优秀

方法 参数(类型) 描述
appendChild(newDom) node 必传 向节点中插入一个元素节点
createElement(node) String 必传 创建一个虚拟节点 此节点创建时还没被渲染到页面中
createTextNode(text) String 必传 创建的文本内容
join(separator) String 可选 参数指定返回时要使用的分隔符分割数组item。 把数组中所有的元素放到一串字符串中返回
属性 描述
nodeType 属性以数字值返回指定节点的节点类型。元素节点为"1" 属性节点为:“2” 文本节点为:“3” 注释节点为:“8” 不是有效节点没有返回 直接"undefined" 该属性只读
nodeName 属性返回节点的名称 注意是大写
nodeValue 属性返回或设置当前节点的值,格式为字符串
childNodes 属性返回所有子节点集合
firstChild 属性返回第一个子节点
lastChild 属性返回最后一个子节点

写在最后:
在这里插入图片描述
在这里插入图片描述

不知不觉 贴吧的贴子也上千评论了 几个月以来阅读量也达到了4.2万 也因此结识了不少爱好前端的朋友 我们也拥有一个温馨的小群 谢谢一路以来的勉励 谨以此篇 宣告开启前端新的修炼之路.人生就如烟火 如果注定不能成为永恒,那就努力做那刹那!
初次练手之作.匆匆完成.不足之处欢迎勘误指正!

标签:Node,appendChild,execute,value,列表,window,let,document,节点
来源: https://blog.csdn.net/meisnb/article/details/106773896

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有