推荐先阅读样例, 之后回来看概念更便于理解
完全是纯手工翻译, 翻译不易, 有帮助的话点个赞吧!
innerHTML vs innerText vs textContent – What's the Difference?
原文链接: freeCodeCamp article By Benjamin Semah
在HTML中, innerHTML, innerText, 和 textContent 是DOM的一些属性, 能够让你读取或更新HTML的内容.
但是它们在包含不同内容时和在处理 HTML 标记上, 都会有不同的行为.
读完本文后, 你将会知道这三种属性有什么不同, 并且明白在什么时候适合使用哪一个?
内容目录
- 什么是
innerHTML属性? - 什么是
innerText属性? - 什么是
textContent属性? - 怎么使用
innerHTML,innerText和textContent读取内容? - 怎么使用
innerHTML,innerText和textContent更新内容? - 使用
innerHTML的安全问题 - 总结
首先, 我将解释这三个属性是怎么工作的, 然后你将通过一些用例来学习它们之间的行为有什么不同.
什么是 innerHTML 属性?
当使用 innerHTML 属性时, 它会读取 HTML 标记和该元素的文本内容二者. 这意味着当使用 innerHTML 设置这个元素的内容, 你可以包含 HTML 标签, 此时浏览器可以正确地渲染它们.
但是要注意, 如果你要从用户或者其他不可行来源使用 innerHTML 插入内容的话, 不怀好意的攻击者就会使用 HTML 的 <script> 标签在你的 app 中插入一些危险代码, 待会文章末尾会详细谈到.
什么是 innerText 属性?
这个属性重点是渲染文本内容, 当你使用 innerText 来读取某个元素的内容时, 它会返回文本在屏幕上的显示效果. 它会忽略 HTML 标签, 并且不显示使用 CSS 隐藏了的内容
当你需要考虑样式时, 你应考虑使用 innerText. 调整某个元素的 innerText 意味着浏览器也许会需要调整布局来适配文本大小的改变, 这暗含了一些性能上的调整.
什么是 textContent 属性?
textContent 属性也会忽略所有HTML标签并且只返回它的文本. 与 innerText 属性读取在屏幕上渲染的文本不同的是, textContent只是读取起到标记作用的文本, 意思是它将返回所有文本, 无论是否会在屏幕上渲染.
还有, textContent 只处理原始文本并不考虑样式, 所以在考虑性能而不考虑样式的情况下, textContent 是相对于innerText更高效的选择.
怎么使用 innerHTML, innerText 和 textContent 读取内容?
现在, 让我们在进入实操环节, 加深我们对这三种属性的理解.
下面是一个简单的四个选项的导航栏标记, 最后一个文本为 "Pricing" 的元素被隐藏了( display 属性设置成 none ). 让我们用三种属性来看一看 nav 元素会有什么不同吧.
<nav>
<a>Home</a>
<a>About</a>
<a>Contact</a>
<a style="display: none">Pricing</a>
</nav>
一个简单的导航栏
使用 innerHTML 获取内容
// 使用 innerHTML 获取内容
const navElement = document.querySelector('nav')
console.log(navElement.innerHTML)
innerHTML 例子, 标记和文本均包含
innerHTML 属性返回所有内容, 包括 nav 元素里的所有HTML标签及其文本内容
使用 innerText获取内容
// 使用 innerText 获取内容
const navElement = document.querySelector('nav')
console.log(navElement.innerText)
innerText 例子, 打印出显示在屏幕上的效果
innerText 属性返回渲染在屏幕上的内容, 忽略所有 HTML 标签. 也忽略被隐藏的内容(即 display 属性设置成 none )
使用 textContent 获取内容
// 使用 `textContent` 获取内容
const navElement = document.querySelector('nav')
console.log(navElement.textContent)
textContent 例子, 打印出标记中的文本包括隐藏的文本👆
textContent 属性返回在HTML标记中的内容. 类似于 innerText , 忽略HTML标签, 但不同的是, textContent 并不考虑样式, 所以会返回 "Pricing" , 就算它被设置成隐藏.
怎么使用 innerHTML, innerText 和 textContent 更新内容?
这三种属性均可以用来更新DOM元素的内容. 当更新内容时, 这些属性的使用与读取内容相似.
让我们用一些例子来深入理解吧
使用 innerHTML 更新内容
以下标记包括一个header元素和一个空的 <ul> 元素, 你可以使用 innerHTML 属性来插入某些内容到 <ul> 中
<h2>Programming languages</h2>
<ul class="languages-list"></ul>
const langListElement = document.querySelector('.languages-list')
// 使用innerHTML设置或更新内容
langListElement.innerHTML = `
<li>JavaScript</li>
<li>Python</li>
<li>PHP</li>
<li>Ruby</li>
`
一个使用 innerHTML 更新内容的例子👆
这些 JavaScript 代码传递HTML列表的字符串给 innerHTML , innerHTML 属性便识别HTML标签并将内容进行对应的排版
不像 innerHTML, innerText 和 textContent 会忽略HTML标签并将所有内容按字符串渲染.
使用 innerText 更新内容
同一个例子, 让我们看看 innerText 属性会怎样更新这个编程语言( Programming languages )的列表
const langListElement = document.querySelector('.languages-list')
langListElement.innerText = `
<li>JavaScript</li>
<li>Python</li>
<li>PHP</li>
<li>Ruby</li>
`
一个使用innerText更新内容的例子👆
注意 innerText 是怎么忽略 HTML 标签并把部分文本打印在屏幕上的. 但是像换行和空格这样的格式仍会保留.
使用 textContent 更新内容
当我们设置或更新内容时, textContent 属性会忽略 HTML 标记并忽略像换行空格这样的格式
const langListElement = document.querySelector('.languages-list')
langListElement.textContent = `
<li>JavaScript</li>
<li>Python</li>
<li>PHP</li>
<li>Ruby</li>
`
因为 textContent 会忽略换行空格这样的格式, 所有文本就会打印在同一行.当你想要原始文本而不考虑文本格式时, textContent 是一个合适的选择.
使用innerHTML的安全问题
因为 innerHTML 处理和解释 HTML 标签, 所以建议只在从可信源插入内容时使用. 或者你有可靠的过滤和验证内容的方法.
浏览器会运行你放在 HTML 标签里的任何 JavaScript 代码. 并且它会打开Cross-Site Scripting (XSS) 的大门, 在那儿攻击者可以向你的网页中注入并运行恶意脚本
看一个例子
<div id="commentSection"></div>
假设你正在使用以上 div 作为一个你的app里用户评价的容器. 而你使用 innerHTML 来添加评论, 却对评论不做任何验证或过滤
以下是一个最简单的一个用户如何注入并运行一个恶意脚本的例子
const commentSection = document.getElementById('commentSection')
let userComment = `<img src="malicious-script.jpg" onerror="alert('Malicious Script Executed!')"> This is my comment!`;
commentSection.innerHTML = userComment;
恶意脚本在innerHTML中通过
<script> 标签运行
这个用户故意给图片一个无效的 src 属性. 这样就会触发 onerror 事件即发出 "Malicious Script Executed!" 的弹窗.
你可以想象攻击者如何利用这个来注入有害的 JavaScript 代码, 很可能窃取用户敏感信息, 操纵网页, 或者进行其他恶意行为
结论
你可以使用这三个属性 innerHTML, innerText, 和 textContent 来操控DOM元素的内容.但是它们的使用方法各不相同, 了解了其中的区别可以让你做出正确的使用选择.
innerHTMl 属性可以识别 HTML 标签并根据标签渲染内容, 而 textContent 忽略 HTML 标签并只把内容看作文本. 你又学了 innerHTML 可能带来安全隐患, 所以需要谨慎使用.
当然, innerText 读取的内容和它在屏幕上出现一样, 并忽略隐藏的内容, 保留原有格式.
但是 textContent 读取的内容和它出现在标记中的一样, 所以它会读取隐藏内容, 但是会忽略你用来设置内容的格式例如换行和空格.
感谢阅读, 编码愉快!