应使用 querySelectorAll 代替 getElementsByClassName:前者返回静态 NodeList,遍历稳定;后者返回实时 HTMLCollection,DOM 变化会导致长度突变、索引错位或死循环。

用 querySelectorAll 代替 getElementsByClassName 遍历元素集合
实时 HTMLCollection(如 getElementsByClassName 返回值)会在 DOM 变化时自动更新,导致遍历时长度突变、索引错位甚至死循环。而 querySelectorAll 返回静态 NodeList,遍历过程稳定可靠。
常见错误是写成:
const items = document.getElementsByClassName('item');
for (let i = 0; i
<p>正确做法是:</p>
- 统一用
document.querySelectorAll('.item')获取快照 - 用
forEach或for...of遍历,避免手动管理索引 - 若需倒序删除(防止索引偏移),可用
Array.from(items).reverse()
遍历表格数据时别直接读 innerText,优先用 textContent
innerText 触发重排(layout),因为它要计算样式后的渲染文本;而 textContent 仅读取 DOM 树中的原始文本节点,性能高且行为确定。
尤其在处理百行以上表格时,差异明显:
- 用
row.cells[i].textContent替代row.cells[i].innerText - 若需过滤空白或换行,再额外 trim,不要依赖
innerText的“格式化”假象 - 注意:
textContent不会解析 HTML 实体(如),需手动 decode 若有需要
动态插入大量 HTML 片段时,必须用 DocumentFragment 中转
直接对容器反复调用 innerHTML += htmlStr 或 appendChild,每次都会触发一次回流(reflow)和样式重算,100 条记录可能卡顿明显。
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
正确路径是离线构建、一次性挂载:
- 创建
const frag = document.createDocumentFragment() - 循环中用
frag.appendChild(newEl)或frag.append(...els) - 最后只执行一次
container.appendChild(frag) - 避免在循环内读取
offsetHeight、getComputedStyle等强制同步布局的 API
遍历含 的结构时,别漏掉 content 属性
的子节点不在主 DOM 树中,其内容藏在 template.content 这个 DocumentFragment 里。直接 template.children 或 template.querySelector 永远为空。
典型误操作:
const tmpl = document.querySelector('#row-tmpl');
console.log(tmpl.children); // []
console.log(tmpl.querySelector('td')); // null
必须显式访问 content:
-
tmpl.content.querySelector('td')才能拿到模板内的节点 - 克隆时用
tmpl.content.cloneNode(true),不是tmpl.cloneNode(true) - 插入前记得用
document.importNode(跨文档场景)或直接append(同文档)
真正容易被忽略的是:遍历逻辑一旦嵌套了异步操作(比如在循环里发 fetch),就不再是“遍历”而是“并发控制”问题——此时 for...of + await 会串行阻塞,而 Promise.all 并发又可能压垮服务端。得先明确你要的是顺序执行、并行加载,还是节流调度。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










