element.innerHTML
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.
Element.innerHTML
属性设置或获取 HTML 语法表示的元素的后代。
备注:如果一个 <div>
, <span>
, 或 <noembed>
节点有一个文本子节点,该节点包含字符 (&)
, (<)
, 或 (>)
, innerHTML
将这些字符分别返回为 &, < 和 >。使用Node.textContent
可获取一个这些文本节点内容的正确副本。
如果要向一个元素中插入一段 HTML,而不是替换它的内容,那么请使用 insertAdjacentHTML()
方法。
语法
const content = element.innerHTML;
element.innerHTML = htmlString;
值
DOMString
包含元素后代的 HTML 序列。设置元素的 innerHTML
将会删除所有该元素的后代并以上面给出的 htmlString 替代。
例外
SyntaxError
当 HTML 没有被正确标记时,设置 innerHTML
将会抛出语法错误。
NoModificationAllowedError
当父元素是 Document
时,设置 innerHTML
将会提示不允许修改。
使用说明
innerHTML
属性可以用来检查当前页面自最初加载到当前的 HTML 源码的变化。
获取元素的 HTML
获取 innerHTML
会导致用户代理序列化 由元素后代组成的 HTML 或者 XML。返回结果字符串。
let contents = myElement.innerHTML;
查看元素内容节点的 HTML 标记。
备注:返回的 HTML 或者 XML 片段是基于当前元素的内容生成的,所以返回的标记和格式可能与原始页面的标记不匹配。
替换元素的内容
设置 innerHTML
的值可以让你轻松地将当前元素的内容替换为新的内容。
举个例子来说,你可以通过文档 body
属性删除 body 的全部内容。
document.body.innerHTML = "";
下面这个例子,首先获取文档当前的 HTML 标记并替换 "<"
字符为 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
节点。
安全问题
用 innerHTML
插入文本到网页中并不罕见。但这有可能成为网站攻击的媒介,从而产生潜在的安全风险问题。
const 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 5 中指定不执行由 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) {
var logElem = document.querySelector(".log");
var time = new Date();
var timeStr = time.toLocaleTimeString();
logElem.innerHTML += timeStr + ": " + msg + "<br/>";
}
log("Logging mouse events inside this container...");
log() 函数通过 Date
对象的 toLocaleTimeString()
方法获取当前时间,然后将消息文本和时间戳放一起构建一个字符串,最后将其追加到具有“log”类的框上。
现在添加第二个方法:记录基于事件 (比如 mousedown
, click
, 和 mouseenter
) 的 MouseEvent
的信息。
function logEvent(event) {
var msg =
"Event <strong>" +
event.type +
"</strong> at <em>" +
event.clientX +
", " +
event.clientY +
"</em>";
log(msg);
}
然后我们使用它作为包含我们消息的框上的鼠标事件的事件处理程序:
var 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;
}
结果
结果就像下面展示的那样。你可以通过移动鼠标进出盒子,点击盒子等等来查看记录输出。
规范
Specification |
---|
HTML Standard # dom-element-innerhtml |
浏览器兼容性
BCD tables only load in the browser
参见
Node.textContent
andNode.innerText
Element.insertAdjacentHTML()
- Parsing HTML into a DOM tree:
DOMParser
- Serializing XML or HTML into a DOM tree:
XMLSerializer