元素:innerHTML 属性

The Element 属性 innerHTML 获取或设置元素内包含的 HTML 或 XML 标记。

更准确地说,innerHTML 获取元素内嵌套的子 DOM 元素的序列化,或设置应解析以替换元素内 DOM 树的 HTML 或 XML。

要将 HTML 插入文档而不是替换元素的内容,请使用 insertAdjacentHTML() 方法。

从属性读取的 DOM 树的序列化不包括 阴影根 - 如果您想获取包含阴影根的 HTML 字符串,则必须使用 Element.getHTML()ShadowRoot.getHTML() 方法。类似地,当使用 innerHTML 设置元素内容时,HTML 字符串被解析为不包含阴影根的 DOM 元素。

例如,<template> 被解析为 HTMLTemplateElement,无论是否指定了 shadowrootmode 属性。为了从包含声明式阴影根的 HTML 字符串设置元素的内容,您必须使用 Element.setHTMLUnsafe()ShadowRoot.setHTMLUnsafe()

包含元素后代的 HTML 序列化的字符串。设置 innerHTML 的值将删除所有元素的后代,并用通过解析字符串 htmlString 中给定的 HTML 构建的节点替换它们。

当设置为 null 值时,该 null 值将转换为空字符串 (""),因此 elt.innerHTML = null 等效于 elt.innerHTML = ""

异常

SyntaxError DOMException

如果尝试使用格式不正确的 HTML 字符串设置 innerHTML 的值,则会抛出该异常。

NoModificationAllowedError DOMException

如果尝试将 HTML 插入到父节点为 Document 的节点中,则会抛出该异常。

使用说明

读取元素的 HTML 内容

读取 innerHTML 会导致用户代理序列化由元素后代组成的 HTML 或 XML 片段。返回的结果字符串。

js
let contents = myElement.innerHTML;

这使您可以查看元素内容节点的 HTML 标记。

注意:返回的 HTML 或 XML 片段是根据元素的当前内容生成的,因此返回片段的标记和格式可能与原始页面标记不匹配。

替换元素的内容

设置 innerHTML 的值使您可以轻松地用新内容替换元素的现有内容。

警告:如果要插入的字符串可能包含潜在的恶意内容,这会成为一个 安全风险。插入用户提供的数据时,您应该始终考虑使用消毒库,以在插入内容之前对其进行消毒。

例如,您可以通过清除文档的 body 属性的内容来完全擦除文档的全部内容。

js
document.body.textContent = "";

此示例获取文档的当前 HTML 标记,并将 "<" 字符替换为 字符引用 "&lt;",从而基本上将 HTML 转换为纯文本。然后,它被包裹在一个 <pre> 元素中。然后,innerHTML 的值更改为此新字符串。结果,文档内容被替换为页面整个源代码的显示。

js
document.documentElement.innerHTML = `<pre>${document.documentElement.innerHTML.replace(
  /</g,
  "&lt;",
)}</pre>`;

操作细节

当您设置 innerHTML 的值时,究竟发生了什么?这样做会导致用户代理执行以下步骤

  1. 指定的值被解析为 HTML 或 XML(基于文档类型),生成一个 DocumentFragment 对象,该对象表示新元素的新 DOM 节点集。
  2. 如果要替换其内容的元素是 <template> 元素,则 <template> 元素的 content 属性被步骤 1 中创建的新 DocumentFragment 替换。
  3. 对于所有其他元素,元素的内容将被新 DocumentFragment 中的节点替换。

将 HTML 附加到元素

设置 innerHTML 的值使您可以将新内容附加到元素的现有内容。

例如,我们可以将一个新的列表项 (<li>) 附加到现有的列表 (<ul>)

HTML

html
<ul id="list">
  <li><a href="#">Item 1</a></li>
  <li><a href="#">Item 2</a></li>
  <li><a href="#">Item 3</a></li>
</ul>

JavaScript

js
const list = document.getElementById("list");

list.innerHTML += `<li><a href="#">Item ${list.children.length + 1}</a></li>`;

请注意,使用 innerHTML 附加 HTML 元素(例如 el.innerHTML += "<a href='…'>link</a>")会导致之前设置的任何事件监听器被删除。也就是说,在您以这种方式附加任何 HTML 元素后,您将无法监听之前设置的事件监听器。

安全注意事项

使用 innerHTML 将文本插入网页并不罕见。这有可能成为网站的攻击媒介,造成潜在的安全风险。

js
let name = "John";
// assuming 'el' is an HTML DOM element
el.innerHTML = name; // harmless in this case

// …

name = "<script>alert('I am John in an annoying alert!')</script>";
el.innerHTML = name; // harmless in this case

虽然这看起来像一个 跨站点脚本 攻击,但结果是无害的。HTML 规定,使用 innerHTML 插入的 <script> 标记 不应该执行

但是,有办法在不使用 <script> 元素的情况下执行 JavaScript,因此,无论何时使用 innerHTML 设置您无法控制的字符串,都会存在安全风险。例如

js
const name = "<img src='x' onerror='alert(1)'>";
el.innerHTML = name; // shows the alert

因此,建议您使用 innerHTML 代替

  • Node.textContent 插入纯文本时,因为它将其插入为原始文本而不是将其解析为 HTML。

警告:如果您的项目将接受任何形式的安全审查,使用 innerHTML 很可能导致您的代码被拒绝。例如,如果您在 浏览器扩展 中使用 innerHTML 并将扩展提交到 addons.mozilla.org,它可能会在审查过程中被拒绝。请参阅 安全地将外部内容插入页面,了解其他方法。

示例

此示例使用 innerHTML 创建一个将消息记录到网页上的框中的机制。

JavaScript

js
function log(msg) {
  const logElem = document.querySelector(".log");

  const time = new Date();
  const timeStr = time.toLocaleTimeString();
  logElem.innerHTML += `${timeStr}: ${msg}<br/>`;
}

log("Logging mouse events inside this container…");

log() 函数通过使用 Date 对象使用 toLocaleTimeString() 获取当前时间,并使用时间戳和消息文本构建字符串来创建日志输出。然后,消息将附加到具有类 "log" 的框中。

我们添加了第二个方法,该方法记录有关 MouseEvent 基于事件(例如 mousedownclickmouseenter)的信息。

js
function logEvent(event) {
  const msg = `Event <strong>${event.type}</strong> at <em>${event.clientX}, ${event.clientY}</em>`;
  log(msg);
}

然后,我们将此用作包含日志的框上多个鼠标事件的事件处理程序。

js
const boxElem = document.querySelector(".box");

boxElem.addEventListener("mousedown", logEvent);
boxElem.addEventListener("mouseup", logEvent);
boxElem.addEventListener("click", logEvent);
boxElem.addEventListener("mouseenter", logEvent);
boxElem.addEventListener("mouseleave", logEvent);

HTML

我们示例的 HTML 非常简单。

html
<div class="box">
  <div><strong>Log:</strong></div>
  <div class="log"></div>
</div>

具有类 "box"<div> 只是一个用于布局目的的容器,它将内容呈现为周围带有框的内容。类为 "log"<div> 是日志文本本身的容器。

CSS

以下 CSS 为我们的示例内容设置样式。

css
.box {
  width: 600px;
  height: 300px;
  border: 1px solid black;
  padding: 2px 4px;
  overflow-y: scroll;
  overflow-x: auto;
}

.log {
  margin-top: 8px;
  font-family: monospace;
}

结果

结果内容如下所示。您可以通过将鼠标移入移出框、单击它等等来查看日志中的输出。

规范

规范
HTML 标准
# dom-element-innerhtml

浏览器兼容性

BCD 表仅在浏览器中加载

另请参阅