You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

解决removeChild报错:参数非Node类型及删除功能失效问题

解决 TypeError: failed to execute 'removeChild' on 'Node' 问题

这个报错的核心原因很明确:你调用txtTabell.removeChild(tr)时,tr并不是一个有效的DOM节点(大概率是null)。咱们一步步拆解问题:

1. 最直接的问题:删除按钮的传参错误

看你加载内容函数里的这段代码:

onclick="slett('${pk},${pkk}')"

你这里把pkpkk拼成了一个字符串(比如"123,456")传给slett函数,但你的slett函数只接收一个参数pk。这就导致:

  • 函数里的pk实际是"123,456"
  • 然后document.getElementById(${pk})会去查找id为"123,456"的tr,但你的tr的id是单独的pk(比如123),自然找不到,返回null
  • 最后调用removeChild(null)就触发了你看到的报错

修复方案:修正传参方式

把传参改成两个独立的参数:

onclick="slett('${pk}', '${pkk}')"

然后修改slett函数,接收两个参数,分别处理对应的删除逻辑:

function slett(pk, pkk) {
  // 删除数据库中的arrangement数据
  var sletttime = arrangement.child(pk);
  sletttime.remove();
  
  // 删除数据库中的russ数据(复用你之前的fjern逻辑)
  var slettruss = russ.child(pkk);
  slettruss.remove();
  
  // 删除表格中的对应行,先判断节点是否存在
  var tr = document.getElementById(pk);
  if (tr) {
    txtTabell.removeChild(tr);
  }
}

这样就能正确获取到对应的tr节点了。

2. 额外的潜在问题:重复添加DOM节点

你的hentArrangement函数里用了txtTabell.innerHTML += ...,如果这个函数被多次调用(比如实时监听数据变化时),会重复添加相同的tr,导致页面出现多个id相同的元素。DOM中id必须唯一,这会导致getElementById只能找到第一个匹配的元素,后续的删除操作会失效。

优化建议:

每次加载数据前先清空原有内容,避免重复添加:

function hentArrangement(snapshot){
  // 先清空表格内容,避免重复渲染
  txtTabell.innerHTML = '';
  txtTabell2.innerHTML = '';
  
  // 遍历snapshot中的子节点(实时监听时必须用forEach)
  snapshot.forEach(function(childSnapshot) {
    var pk = childSnapshot.key;
    var nyTime = childSnapshot.val();
    var russRef = database.ref("russ/" + nyTime.russ);
    
    russRef.on("value", function(snapshotruss){
      var pkk = snapshotruss.key;
      var russObj = snapshotruss.val();
      
      txtTabell.innerHTML += `
        <tr id="${pk}">
          <td><label class="russlabel" onclick="edit('${pk}')">${nyTime.arrangør}</label><input type="text" class="editItem" style="display:none"></td>
          <td>${nyTime.adresse}</td>
          <td>${nyTime.postadresse}</td>
          <td>${nyTime.poststed}</td>
          <td>${nyTime.pris}</td>
          <td>${russObj.navn}</td>
          <td>${russObj.russadresse}</td>
          <td>${russObj.mobilnr}</td>
          <td>${russObj.kjonn}</td>
        </tr>`;
      
      // 修复tr标签的id写法错误:<tr =${pkk}> → <tr id="${pkk}">
      txtTabell2.innerHTML +=`
        <tr id="${pkk}">
          <td>${russObj.navn}</td>
          <td>${russObj.russadresse}</td>
          <td>${russObj.mobilnr}</td>
          <td>${russObj.kjonn}</td>
          <td><label class="delete" onclick="slett('${pk}', '${pkk}')"><button>Slett</button></label></td>
        </tr>`;
    });
  });
}

另外注意你在txtTabell2里的tr标签写错了:<tr =${pkk}>应该改成<tr id="${pkk}">,否则这个tr也没有正确的id标识。

3. 最后:添加节点存在性判断

在删除DOM节点前,先判断节点是否存在且属于目标父节点,即使后续有意外情况,也不会抛出报错:

var tr = document.getElementById(pk);
if (tr && tr.parentNode === txtTabell) {
  txtTabell.removeChild(tr);
}

按照上面的步骤修改后,你的删除功能应该就能恢复正常了。

内容的提问来源于stack exchange,提问作者Raahim Khan

火山引擎 最新活动