元素: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 片段。返回的结果字符串。
let contents = myElement.innerHTML;
这使您可以查看元素内容节点的 HTML 标记。
注意:返回的 HTML 或 XML 片段是根据元素的当前内容生成的,因此返回片段的标记和格式可能与原始页面标记不匹配。
替换元素的内容
设置 innerHTML
的值使您可以轻松地用新内容替换元素的现有内容。
警告:如果要插入的字符串可能包含潜在的恶意内容,这会成为一个 安全风险。插入用户提供的数据时,您应该始终考虑使用消毒库,以在插入内容之前对其进行消毒。
例如,您可以通过清除文档的 body
属性的内容来完全擦除文档的全部内容。
document.body.textContent = "";
此示例获取文档的当前 HTML 标记,并将 "<"
字符替换为 字符引用 "<"
,从而基本上将 HTML 转换为纯文本。然后,它被包裹在一个 <pre>
元素中。然后,innerHTML
的值更改为此新字符串。结果,文档内容被替换为页面整个源代码的显示。
document.documentElement.innerHTML = `<pre>${document.documentElement.innerHTML.replace(
/</g,
"<",
)}</pre>`;
操作细节
当您设置 innerHTML
的值时,究竟发生了什么?这样做会导致用户代理执行以下步骤
- 指定的值被解析为 HTML 或 XML(基于文档类型),生成一个
DocumentFragment
对象,该对象表示新元素的新 DOM 节点集。 - 如果要替换其内容的元素是
<template>
元素,则<template>
元素的content
属性被步骤 1 中创建的新DocumentFragment
替换。 - 对于所有其他元素,元素的内容将被新
DocumentFragment
中的节点替换。
将 HTML 附加到元素
设置 innerHTML
的值使您可以将新内容附加到元素的现有内容。
例如,我们可以将一个新的列表项 (<li>
) 附加到现有的列表 (<ul>
)
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
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
将文本插入网页并不罕见。这有可能成为网站的攻击媒介,造成潜在的安全风险。
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
设置您无法控制的字符串,都会存在安全风险。例如
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
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
基于事件(例如 mousedown
、click
和 mouseenter
)的信息。
function logEvent(event) {
const msg = `Event <strong>${event.type}</strong> at <em>${event.clientX}, ${event.clientY}</em>`;
log(msg);
}
然后,我们将此用作包含日志的框上多个鼠标事件的事件处理程序。
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 非常简单。
<div class="box">
<div><strong>Log:</strong></div>
<div class="log"></div>
</div>
具有类 "box"
的 <div>
只是一个用于布局目的的容器,它将内容呈现为周围带有框的内容。类为 "log"
的 <div>
是日志文本本身的容器。
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 表仅在浏览器中加载
另请参阅
Node.textContent
和HTMLElement.innerText
Element.insertAdjacentHTML()
Element.outerHTML
- 将 HTML 或 XML 解析为 DOM 树:
DOMParser
- 将 DOM 树序列化为 XML 字符串:
XMLSerializer
Element.getHTML()
ShadowRoot.getHTML()
Element.setHTMLUnsafe()
ShadowRoot.setHTMLUnsafe()