小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
上一篇文章中我们使用appendChild()
方法将我们创建的DOM元素插入到指定的父元素的最后位置。今天我们继续来看看这几个API,textContent
、innerText
、innerHTML
,它们都是比较常用的,用来获取和设置HTML的内容或者标签。下面我们从appendChild
开始
appendChild()
我们来复习一下语法
parentNode.appendChild(childNode);
appendChild()
将传入的childNode
插入到parentNode
的最后一个子元素的后面,并返回插入的元素。
如果childNode
是页面中已经存在的DOM节点,那么appendChild()
方法将会把childNode
从原来的位置移动到新的位置。
先来回顾一下appendChild()
基础使用
基础用法例子
<ul id="menu">
</ul>
<script>
function createMenuItem(name) {
let li = document.createElement('li');
li.textContent = name;
return li;
}
// 获取ul#menu元素
const menu = document.querySelector('#menu');
// 添加子元素
menu.appendChild(createMenuItem('首页'));
menu.appendChild(createMenuItem('产品'));
menu.appendChild(createMenuItem('关于我们'));
</script>
运行后,HTML如下
移动节点例子
我们的HTML如下
<ul id="first-list">
<li>HTML</li>
<li>CSS</li>
<li>JavaScript</li>
</ul>
<ul id="second-list">
<li>Vue</li>
<li>React</li>
<li>Angular</li>
</ul>
<script>
// 获取#first-list元素
const firstList = document.querySelector('#first-list');
// 获取第一个子元素
const htmlElement = firstList.firstElementChild;
// 获取#second-list元素
const secondList = document.querySelector('#second-list');
// 将htmlElement元素插入到secondList中
secondList.appendChild(htmlElement);
</script>
运行后,HTML如下,可以看到#first-list
元素中的第一个子元素,被移动到#second-list
元素内的最后一个元素。
textContent
textContent
属性用来获取节点以及子节点的文本内容。
获取文本内容
<div id="note">
JavaScript textContent Demo!
<span style="display:none">隐藏文本内容!</span>
<!-- 这是一段注释 -->
</div>
<script>
let note = document.getElementById('note');
console.log(note.textContent);
// 输出:
// JavaScript textContent Demo!
// 隐藏文本内容!
</script>
可以看到textContent
不光获取div#note
下的文本内容,同时也获取到了隐藏的span
元素下的文本内容,不包含注释内容。
textContent
对比 innerText
innerText
考虑了 CSS 样式,不返回隐藏元素内的内容。
<div id="note">
JavaScript textContent Demo!
<span style="display:none">隐藏文本内容!</span>
<p>我是一段文本内容</p>
<!-- 这是一段注释 -->
</div>
<script>
let note = document.getElementById('note');
console.log(note.innerText);
// 输出:
// JavaScript textContent Demo!
// 我是一段文本内容
</script>
由于innerText 属性使用最新的CSS 来计算文本,因此使用它会触发重排,会耗费一些性能。
当浏览器需要处理和绘制部分或者全部网页时,就会发生回流
设置textContent
除了读取textContent
属性,我们还可以使用textContent
属性来设置节点的文本。
<div id="note">
JavaScript textContent Demo!
<span style="display:none">隐藏文本内容!</span>
<p>我是一段文本内容</p>
<!-- 这是一段注释 -->
</div>
<script>
let note = document.getElementById('note');
note.textContent = '新设置的文本';
</script>
运行之后我们会发现div#note
的所有子节点都被删除并替换成了我们设置的新文本。
<div id="note">新设置的文本</div>
innerHTML
innerHTML
用来获取元素中包含的HTML标签
获取HTML
<div id="note">
JavaScript textContent Demo!
<span style="display:none">隐藏文本内容!</span>
<!-- 这是一段注释 -->
</div>
<script>
let note = document.getElementById('note');
console.log(note.innerHTML);
// 输出:
// JavaScript textContent Demo!
// <span style="display:none">隐藏文本内容!</span>
// <!-- 这是一段注释 -->
</script>
设置HTML
清空body内的所有html
document.body.innerHTML = '';
安全风险
HTML5规范,不应该使用innerHTML
插入<script>
标签
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JavaScript innerHTML</title>
</head>
<body>
<div id="main"></div>
<script>
const main = document.getElementById('main');
const scriptHTML = `<script>alert("我是innerHTML的alert");</script>`;
main.innerHTML = scriptHTML;
</script>
</body>
</html>
以上代码中,<script>
标签内的 alert() 不会被执行
我们修改一下代码
const main = document.getElementById('main');
const externalHTML = `<img src='1' onerror='alert("图片加载失败")'>`;
main.innerHTML = externalHTML;
由于图片无法正常加载,onerror
将会执行,所以alert
代码将会执行,我们可以在onerror
内加入一些恶意代码。
所以,我们不应该使用innerHTML去设置一些无法控制的内容,否则就会面临安全风险。
所以要插入一些纯文本插入到文档中,使用 textContent 属性而不是 innerHTML。 textContent 不会被解析 HTML,而是作为原始文本。
总结
今天我们复习了appendChild()
、 textContent
、innerText
、innerHTML
的使用。
我们明天继续。
如果你想跟着我一起复习DOM知识,微信搜索【小帅的编程笔记】,每天更新