必须用innerHTML仅当插入带标签的HTML结构;该用textContent时用于纯文本且需防XSS、保性能。追加内容禁用+=,应选insertAdjacentHTML或textContent+=。

innerHTML 和 textContent 都能改元素内容,但选错会导致 XSS、样式丢失、隐藏文本意外暴露或性能浪费——关键看你要不要解析 HTML。
什么时候必须用 innerHTML
只有当你需要插入带标签的结构(比如按钮、列表、带样式的片段)时,innerHTML 才不可替代。
- 它会把字符串当作 HTML 解析,自动创建节点,
<strong>加粗</strong>真的会加粗 - 直接替换整个子树,原有事件监听器全部丢失(哪怕你只改一个字)
- 如果字符串来自用户输入(如表单、URL 参数),不转义就赋值,
<script>alert(1)</script>会执行 - 频繁设置大段 HTML 会触发重排重绘,比纯文本慢得多
示例:el.innerHTML = '<button onclick="doIt()">点我</button>' —— 这里 onclick 是有效绑定的,但后续所有子元素的原事件都清空了。
什么时候该用 textContent
只要内容是纯文本,或者你明确不想让浏览器解析任何标签,就用 textContent。
立即学习“前端免费学习笔记(深入)”;
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
- 它无视 HTML 标签,
<p>hello</p>会被当作文本显示成 “<p>hello</p>”,不是段落 - 保留隐藏元素(
display: none或visibility: hidden)里的文本,innerText不会 - 执行快、无 XSS 风险、不触发 DOM 重建,适合高频更新(如计数器、日志输出)
- 注意:它会把所有子节点文本拼成一行,换行符、缩进全丢,
<div>\n <span>a</span>\n <span>b</span>\n</div>的textContent是"ab"
示例:el.textContent = '用户输入:' —— 安全,且不会意外渲染成标签。
innerHTML 追加内容时别直接 +=
写 el.innerHTML += '<li>新项</li>' 看似方便,实际每次都在重新解析整个 HTML 字符串,效率差,还会销毁已有子节点上的事件和状态(比如 <input> 的焦点、滚动位置)。
- 正确做法是用
document.createElement+appendChild,或insertAdjacentHTML('beforeend', ...) -
insertAdjacentHTML支持'beforebegin'、'afterbegin'、'beforeend'、'afterend'四种位置,只解析新增部分 - 如果只是追加文本,
el.textContent += '新文字'更轻量,不涉及 HTML 解析
示例:el.insertAdjacentHTML('beforeend', '<li>动态添加</li>') —— 比 += 安全且快。
容易被忽略的兼容性与边界行为
textContent 在所有现代浏览器中行为一致;innerHTML 虽然也广泛支持,但某些边缘情况仍需留意:
-
script和style标签设入innerHTML后,内容不会执行或生效(除非手动调用eval或插入<link>) - 表格元素(
<table>、<tr>)不能直接用innerHTML设置子元素,必须通过insertRow/insertCell或包裹在合法结构里(如<tbody><tr>...</tr></tbody>) -
textContent对<script>、<style>元素返回的是其内部原始文本(含注释),而innerHTML返回的是经过浏览器规范化后的字符串(可能删掉注释、标准化空格)
真正难处理的不是“怎么写”,而是“改完之后,原来绑的事件还在不在、输入框光标跑哪去了、隐藏区域的文本要不要同步”——这些细节不验证,上线后才踩坑。


















