DOM问题核心在于执行时机不对、节点引用失效、操作方式不匹配;document.getElementById返回null主因是脚本执行早于HTML解析,ID含特殊字符需用querySelector并转义,批量操作应使用DocumentFragment避免频繁重排。

别背方法列表,先搞清三个核心矛盾:执行时机不对、节点引用失效、操作方式不匹配场景——90% 的 DOM 问题都卡在这儿。
document.getElementById 为什么总返回 null
不是 ID 写错了,大概率是脚本执行早于 HTML 解析完成。ID 拼写错误、大小写不一致、ID 含点号或冒号(如 user.name)也会触发这个结果。
- 把
<script>标签移到</body>前是最简单可靠的解法 - 或者用
document.addEventListener('DOMContentLoaded', ...)包裹操作逻辑 - ID 含特殊字符时必须改用
document.querySelector('#user\.name'),getElementById不支持转义
querySelector 和 querySelectorAll 的关键区别
querySelector 返回第一个匹配的 Element 或 null;querySelectorAll 返回 NodeList(类数组,但不是 Array),不能直接调用 map 或 forEach。
- 要遍历多个元素:用
[...document.querySelectorAll('.item')].forEach(...)或Array.from(...).map(...) - 只取一个且不确定是否存在:优先用
querySelector,比getElementById更灵活,支持[data-id="123"]、.container > .item:first-child等复杂定位 - 性能上两者差异极小,但
querySelectorAll在匹配大量节点时会略慢,非必要不滥用通配符选择器(如*或div p span)
innerHTML、textContent、innerText 怎么选
innerHTML 解析 HTML 字符串,有 XSS 风险;textContent 只处理纯文本,安全且快;innerText 受 CSS 影响(如 display: none 的内容不计入),且在旧版 IE 行为不一致。
立即学习“前端免费学习笔记(深入)”;
- 填表单提示、渲染用户昵称、显示 API 描述字段 → 无条件用
textContent - 需要插入带样式的结构化内容(如富文本片段)→ 用
insertAdjacentHTML('beforeend', htmlStr),避免覆盖已有事件绑定 - 绝对不要写
el.innerHTML += '<div>new</div>':这是读取 + 解析 + 重写三步,清空输入框值、丢失焦点、移除监听器
动态增删元素时最容易踩的坑
循环中反复调用 appendChild 或 insertBefore 会频繁触发重排重绘,50 条以上列表性能断崖式下降。
- 批量插入:先创建
document.createDocumentFragment(),所有appendChild都对它操作,最后再一次性挂到真实 DOM 上 - 删除元素:必须确保目标节点是父节点的直属子节点,否则
removeChild报错;更稳妥写法是el?.parentElement?.removeChild(el) - 绑定事件别用
onclick:重复赋值会覆盖前一个 handler;始终用addEventListener,解绑时传入同一函数引用(别用箭头函数)
DOM 操作的复杂点不在 API 数量,而在节点生命周期与浏览器渲染机制的耦合——比如 textContent 改完立刻可读,但 style.color = 'red' 后立即读 offsetHeight 可能触发强制同步布局。这些隐性依赖,才是调试时最耗时间的地方。



















