DOM操作核心在于节点关系与执行时机:脚本需在DOM就绪后执行,innerHTML是赋值非追加,removeChild需确保节点存在且为直属子节点,style仅操作内联样式,节点存在性与引用管理是关键。

DOM 操作不是“学完就通”,而是“用错就报错”——关键不在记方法名,而在理解节点关系和执行时机。
获取元素时为什么 document.getElementById 找不到?
最常见原因是脚本执行早于 HTML 解析完成,document.getElementById 返回 null。不是方法写错了,是执行时机不对。
- 把
<script>放在</body>前(推荐) - 或用
DOMContentLoaded事件包裹操作:document.addEventListener('DOMContentLoaded', () => { const el = document.getElementById('my-id'); // 此时 DOM 已就绪 }); -
getElementById只接受 ID 字符串,不支持 CSS 选择器;ID 中含特殊字符(如点、冒号)需转义:document.getElementById('user.name')会失败,应改用document.querySelector('#user\.name')
用 innerHTML 追加内容为什么覆盖旧内容?
innerHTML 是“赋值”而非“追加”。每次设置都会重写整个子树,已绑定的事件监听器、输入框状态、焦点等全部丢失。
- 要追加:用
insertAdjacentHTML,例如:el.insertAdjacentHTML('beforeend', '<div>new item</div>');其中'beforeend'表示插入到元素末尾子节点之间 - 要保留交互逻辑:优先用 DOM 方法创建节点:
document.createElement+appendChild,避免 HTML 字符串解析开销和 XSS 风险 -
innerHTML += 'xxx'看似追加,实为读取+解析+重写,性能差且清空状态,禁止在循环中使用
removeChild 报错 “NotFoundError” 怎么办?
错误信息直指核心:你传给它的不是该元素的**直属子节点**,或者节点已被移除过一次。
立即学习“前端免费学习笔记(深入)”;
- 安全移除写法:
if (el.parentNode) { el.parentNode.removeChild(el); }或更简洁地用现代 API:el.remove()(IE 不支持,但绝大多数项目已无需兼容) -
removeChild必须传入当前父节点下的真实子节点引用;用querySelector查到的节点若已被移走,再调用removeChild就会报错 - 批量删除子节点别用循环 +
removeChild,容易漏删——直接设el.innerHTML = ''或while(el.firstChild) el.removeChild(el.firstChild)
修改样式为什么 element.style.xxx 不生效?
element.style 只读写 **内联样式(style 属性)**,对 CSS 类、外部样式表、伪元素完全无效。
- 改类名用
classList:el.classList.add('active')、el.classList.toggle('hidden') - 想读计算后样式(比如真实宽度、颜色):必须用
getComputedStyle(el).width,不能靠style.width - CSS 自定义属性(
--main-color)要通过el.style.setProperty('--main-color', 'blue')设置,style对象不会自动映射这些变量
DOM 操作真正的复杂点不在 API 数量,而在于节点是否还“挂”在文档树上、是否被其他代码持有引用、以及浏览器渲染队列的异步性——很多 bug 的根源,是以为节点还在那儿,其实它已经消失了。



















