AR开发中removeChild报错:参数1非Node类型问题求助
问题排查:AR实体切换时的removeChild错误
开发AR功能时,点击按钮创建a-entity正常,但切换按钮时想移除另一按钮生成的实体,触发错误:
Uncaught TypeError: Failed to execute 'removeChild' on 'Node': parameter 1 is not of type 'Node'
错误原因分析
- removeInfoModels逻辑漏洞:
- 当
infoModel3存在时,直接调用wrapper.removeChild(infoModel1),但此时infoModel1可能不存在(比如用户第一次点BSC按钮),传递null给removeChild就会报错。 - else if分支中,
infoModel1存在时去移除infoModel3,但此时infoModel3必然是null(因为前面if条件不满足),同样触发错误。
- 当
- showInfoModels判断逻辑错误:
const question = dataObj.filter(element => element.model2)返回的是数组,数组在if判断中永远为true(哪怕是空数组),导致不管有没有model2都会执行创建两个实体的分支,逻辑不符合预期。
解决方案
1. 修复removeInfoModels函数:安全移除元素
直接使用元素自身的remove()方法(无需依赖父元素,且元素不存在时调用不会报错),或者先判断元素存在再操作:
const removeInfoModels = () => { // 可选链操作符:元素不存在时不会执行后续方法 document.getElementById('eth-1')?.remove(); document.getElementById('eth-2')?.remove(); document.getElementById('bsc-1')?.remove(); }
若环境不支持可选链,可替换为:
const removeInfoModels = () => { const model1 = document.getElementById('eth-1'); const model2 = document.getElementById('eth-2'); const model3 = document.getElementById('bsc-1'); if (model1) model1.remove(); if (model2) model2.remove(); if (model3) model3.remove(); }
2. 修复showInfoModels的判断逻辑
直接检查目标数据是否包含model2,同时简化冗余的遍历逻辑(每个net对应唯一数据,无需forEach):
const showInfoModels = (data, netType) => { removeInfoModels(); const dataObj = data.filter(obj => obj.net === netType); if (!dataObj.length) return; // 无匹配数据时直接返回 const targetData = dataObj[0]; // 创建第一个实体 createEntity2(targetData.model1.id, targetData.model1.scale, targetData.model1.position, targetData.model1.model); // 存在model2时创建第二个实体 if (targetData.model2) { createEntity2(targetData.model2.id, targetData.model2.scale, targetData.model2.position, targetData.model2.model); } }
3. 可选优化:动态管理实体ID(适配后续扩展)
如果后续会新增更多net类型,可从data中动态提取所有实体ID,避免硬编码:
import { data } from './data.js'; const removeInfoModels = () => { data.forEach(item => { document.getElementById(item.model1.id)?.remove(); // 存在model2时才尝试删除 item.model2 && document.getElementById(item.model2.id)?.remove(); }); }
修改后的完整utils.js示例
// 假设wrapper已在外部定义 const removeInfoModels = () => { document.getElementById('eth-1')?.remove(); document.getElementById('eth-2')?.remove(); document.getElementById('bsc-1')?.remove(); } const createEntity2 = (id, scale, position, model) => { const entity = document.createElement('a-entity'); entity.setAttribute('id', id); entity.setAttribute('scale', scale); entity.setAttribute('position', position); entity.setAttribute('gltf-model', `#${model}`); wrapper.appendChild(entity); } const showInfoModels = (data, netType) => { removeInfoModels(); const dataObj = data.filter(obj => obj.net === netType); if (!dataObj.length) return; const targetData = dataObj[0]; createEntity2(targetData.model1.id, targetData.model1.scale, targetData.model1.position, targetData.model1.model); if (targetData.model2) { createEntity2(targetData.model2.id, targetData.model2.scale, targetData.model2.position, targetData.model2.model); } }
内容的提问来源于stack exchange,提问作者alex morales
相关产品推荐
相关产品推荐

