JS DOM 编程复习笔记--appendChild、textContent、innerText、innerHTML(五)

811 阅读3分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

上一篇文章中我们使用appendChild()方法将我们创建的DOM元素插入到指定的父元素的最后位置。今天我们继续来看看这几个API,textContentinnerTextinnerHTML,它们都是比较常用的,用来获取和设置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如下

image-20211021141704035

移动节点例子

我们的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元素内的最后一个元素。

image-20211021143351277

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()textContentinnerTextinnerHTML的使用。

我们明天继续。

如果你想跟着我一起复习DOM知识,微信搜索【小帅的编程笔记】,每天更新