outerHTML/innerHTML
outerHTML
https://developer.mozilla.org/zh-CN/docs/Web/API/Element/outerHTML
element DOM 接口的outerHTML属性获取描述元素(包括其后代)的序列化 HTML 片段。
它也可以设置为用从给定字符串解析的节点替换元素。
要仅获取元素内容的 HTML 表示形式或替换元素的内容,请使用 innerHTML 属性
innerHTML
https://developer.mozilla.org/zh-CN/docs/Web/API/Element/innerHTML
Element.innerHTML 属性设置或获取 HTML 语法表示的元素的后代。
备注: 如果一个 <div>, <span>, 或 <noembed> 节点有一个文本子节点,该节点包含字符 (&), (<), 或 (>), innerHTML 将这些字符分别返回为 &, < 和 >。使用Node.textContent 可获取一个这些文本节点内容的正确副本。
HTML语法表示会对产生歧义的文本内容字符做转义处理
用outerHTML/innerHTML替换内容
可以看到outHTML/innerHTML都有基于字符串模版解析替换元素内容的作用
如下直接查看网页源码,将 HTML 转换成原始文本,将其包裹在 <pre> 元素中
document.documentElement.innerHTML =
"<pre>"+
document.documentElement.innerHTML.replace(/</g,"<")
+"</pre>";
innerHTML 设置一个值的时候到底发生了什么?用户代理按照以下步骤:
给定的值被解析为 HTML 或者 XML(取决于文档类型),结果就是 DocumentFragment 对象代表元素新设置的 DOM 节点。
如果元素内容被替换成 <template> 元素,<template> 元素的 content 属性会被替换为步骤 1 中创建的新的 DocumentFragment。
对于其他所有元素,元素的内容都被替换为新的 DocumentFragment 节点。
用outerHTML/innerHTML替换内容存在的安全问题
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写一个鼠标事件记录器并展示在网页中
https://codepen.io/doudoumao/pen/ZEjwxVd
outerText/innerText
outerText
**HTMLElement.outerText**是一个非标准的属性。作为一个获得器,它返回与HTMLElement.innerText一致的值。作为一个设置器,它将删除当前节点并将其替换为给定的文本。
innerText
HTMLElement.innerText 属性表示一个节点及其后代的“渲染”文本内容
备注: innerText 很容易与Node.textContent混淆,但这两个属性间实际上有很重要的区别。大体来说,innerText 可操作已被渲染的内容,而 textContent 则不会。
一段 DOMString 表示一个元素中已被渲染的内容。如果元素自身没有 被渲染 (e.g 被从文档中删除或没有在视图中显示), 这时返回值与 Node.textContent 属性相同。
示例
对比了 innerText 和 Node.textContent
https://codepen.io/doudoumao/pen/ZEjwoYE
textContent
Node.textContent
Node 接口的 textContent 属性表示一个节点及其后代的文本内容。
备注: textContent 和 HTMLElement.innerText 容易混淆,但这两个属性在重要方面有不同之处 。
取值情况:
备注: 如果你要获取整个文档的文本以及 CDATA data ,可以使用 document.documentElement.textContent。
如果节点是个 CDATA section、注释、processing instruction (en-US) 或者 text node,textContent 返回节点内部的文本内容,例如 Node.nodeValue。
备注: CDATASection 接口用于表示 CDATA 片段(CDATA section)。在 XML 中,CDATA 可以直接包含未经转义的文本。比如 < 和 &,只要位于 CDATA 片段中,它们就不需要被转义,保持原样就可以了。
<foo>这是一个CDATA section: <![CDATA[ < > & ]]> 其中包含了一些没有转义的字符。 </foo>
CDATA 片段不应该在 HTML 中被使用;它只在 XML 中有效。
text node 文本节点
Document.createTextNode() 创建一个新的文本节点。这个方法可以用来转义 HTML 字符。
https://codepen.io/doudoumao/pen/wvxNjLw
对于其他节点类型,textContent 将所有子节点的 textContent 合并后返回,除了注释和 processing instructions。(如果该节点没有子节点的话,返回一个空字符串。)
总结下就是顶层节点返回null,比较特殊的单个节点返回本身文本内容,其它节点遍历以后返回
与 innerText 的区别
textContent 会返回节点中的每一个元素。相反,innerText 受 CSS 样式的影响,并且不会返回隐藏元素的文本,
此外,由于 innerText 受 CSS 样式的影响,它会触发回流( reflow )去确保是最新的计算样式。(回流在计算上可能会非常昂贵,因此应尽可能避免。)
https://codepen.io/doudoumao/pen/ZEjwoYE
与 innerHTML 的区别
正如其名称,Element.innerHTML 返回 HTML。通常,为了在元素中检索或写入文本,人们使用 innerHTML。但是,textContent 通常具有更好的性能,因为文本不会被解析为 HTML。
此外,使用 textContent 可以防止 XSS 攻击。
写文本contentText优先