动态创建元素的getElementById使用,标签页切换removeChild报错求助
问题分析与解决
问题描述
实现标签页切换页面内容功能时,首次点击标签能正常替换内容,但第二次点击就会弹出报错:
Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
问题出在你一开始用let cont = document.getElementById('main-section')存了页面初始化时的那个#main-section元素引用。第一次点击把这个元素移除后,它就脱离DOM树了;之后再点击标签,页面里的#main-section是新创建的元素,旧的cont早就跟当前DOM里的元素没关系了,这时候再执行content.removeChild(cont),肯定会报错。
代码展示
index.js
import pageLoad from './pageLoad'; import nav from "./headers/nav"; import tabs from "./headers/tabs"; //All content is appended to this div. const content = document.createElement('div'); content.setAttribute('id', 'content'); function component(focus) { content.appendChild(nav()); content.appendChild(tabs()); content.appendChild(pageLoad(focus)); return content; } document.body.appendChild(component("home")); let cont = document.getElementById('main-section'); document.getElementById('tab1').addEventListener('click', (e) => { content.removeChild(cont); content.appendChild(pageLoad("home")); }); document.getElementById('tab2').addEventListener('click', (e) => { content.removeChild(cont); content.appendChild(pageLoad("about")); });
pageLoad.js
import home from "./pages/home"; import about from "./pages/about"; export default function pageLoad(focus) { const content = document.createElement('section'); content.setAttribute('class', 'main'); content.setAttribute('id', 'main-section'); if (focus == "home") { content.appendChild(home()); } else if (focus == "about") { content.appendChild(about()); } return content; };
解决方案
方案一:每次点击时重新获取当前的#main-section
不用提前存储cont变量,每次点击操作前,先找到当前DOM中存在的#main-section元素再执行移除和替换:
// 删除原来的let cont = ...这一行 document.getElementById('tab1').addEventListener('click', (e) => { const currentSection = document.getElementById('main-section'); content.removeChild(currentSection); content.appendChild(pageLoad("home")); }); document.getElementById('tab2').addEventListener('click', (e) => { const currentSection = document.getElementById('main-section'); content.removeChild(currentSection); content.appendChild(pageLoad("about")); });
方案二:直接替换元素
用replaceChild方法一步完成元素替换,代码更简洁:
document.getElementById('tab1').addEventListener('click', (e) => { const newSection = pageLoad("home"); const oldSection = document.getElementById('main-section'); content.replaceChild(newSection, oldSection); }); document.getElementById('tab2').addEventListener('click', (e) => { const newSection = pageLoad("about"); const oldSection = document.getElementById('main-section'); content.replaceChild(newSection, oldSection); });
方案三:更新cont变量的引用
如果要保留cont变量,每次创建新元素后更新它的引用,指向新的#main-section:
let cont = document.getElementById('main-section'); document.getElementById('tab1').addEventListener('click', (e) => { content.removeChild(cont); cont = pageLoad("home"); content.appendChild(cont); }); document.getElementById('tab2').addEventListener('click', (e) => { content.removeChild(cont); cont = pageLoad("about"); content.appendChild(cont); });
这三种方案都能解决报错问题,其中方案一和方案二更稳妥,能避免因变量引用过期导致的问题。
内容的提问来源于stack exchange,提问作者Vurnex
相关产品推荐
相关产品推荐

