You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

动态创建元素的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 10:53:14