# JavaScript教程 - 15 DOM

继续讲解 DOM。

# 15.5 文本节点

在前面也说了文本也是节点。

下面再举个例子:

<body>
  <div id="my-div">For技术栈</div>

  <script>
    const element = document.getElementById('my-div');  // 获取到div元素
    console.log(element.firstChild);  // 获取div下的第一个节点,也就是文本节点:For技术栈
  </script>
</body>
1
2
3
4
5
6
7
8
  • 上面就获取到了文本节点。

但是通过获取文本节点再修改文本,太麻烦了,我们一般不这样做,我们只需要获取到文本节点的父节点进行操作就可以了。

所以在上面的代码中,获取 div 元素,就可以修改 div 中的文本了,有三种方式可以获取和修改元素中的文本内容:

  • element.textContent
  • element.innerText
  • element.innerHTML

举个栗子:

<body>
  <div id="box1">For技术栈</div>
  <div id="box2">For技术栈</div>
  <div id="box3">For技术栈</div>

  <script>
    const box1 = document.getElementById('box1');
    const box2 = document.getElementById('box2');
    const box3 = document.getElementById('box3');

    console.log(box1.textContent);  // For技术栈
    console.log(box2.innerText);  // For技术栈
    console.log(box3.innerHTML);  // For技术栈

    box1.textContent = 'For技术栈1';
    box2.innerText = 'For技术栈2';
    box3.innerHTML = 'For技术栈3';
  </script>
</body>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  • 在上面的代码中,可以通过上面三种方式来获取和修改 div 中的文本内容。

问题来了,有什么区别?

在看一个例子:

<body>
  <div id="box1">
    <span>For技术栈</span>
  </div>
  <div id="box2">
    <span>For技术栈</span>
  </div>
  <div id="box3">
    <span>For技术栈</span>
  </div>

  <script>
    const box1 = document.getElementById('box1');
    const box2 = document.getElementById('box2');
    const box3 = document.getElementById('box3');

    console.log(box1.textContent);  // 
    console.log(box2.innerText);  // 
    console.log(box3.innerHTML);  // <span>For技术栈</span>
  </script>
</body>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  • textContentinnerText 获取不到 html 标签,innerText 就是纯文本,textContent 会包括换行符。
  • innerHTML 可以获取到 html 标签内容。

执行结果如下:


再看一下修改文本内容的区别:

<body>
  <div id="box1"></div>
  <div id="box2"></div>
  <div id="box3"></div>

  <script>
    const box1 = document.getElementById('box1');
    const box2 = document.getElementById('box2');
    const box3 = document.getElementById('box3');

    box1.textContent = '<b>For技术栈1</b>';
    box2.innerText = '<b>For技术栈2</b>';
    box3.innerHTML = '<b>For技术栈3</b>';
  </script>
</body>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

显示如下:

可以看到 textContentinnerText 会对文本内容进行转义(例如,大于号转换为 &gt; ),将 html 内容按照文本内容来显示,而 innerHTML 会将 html 内容渲染后显示,但是 innerHTML 这种方式容易存在 xss 注入风险,因为如果文本内容是用户自定义的,用户可以在文本内容中添加 html 内容(插入不和谐的内容,你的网站吃不了兜着走),而且可以添加 <script> 标签引入第三方的 js 脚本去执行,这就很危险了,所以使用 innerHTML 要确保内容是自己的。


textContentinnerText 还有一个区别就是 textContent 获取标签中的内容不会考虑 CSS 样式,而 innerText 会考虑 CSS 样式。

举个栗子:

<body>
  <div id="box1">
    <span style="display: none;">For技术栈</span>
  </div>
  <div id="box2">
    <span style="display: none;">For技术栈</span>
  </div>
  <div id="box3">
    <span style="display: none;">For技术栈</span>
  </div>

  <script>
    const box1 = document.getElementById('box1');
    const box2 = document.getElementById('box2');
    const box3 = document.getElementById('box3');

    console.log(box1.textContent);  // 'For技术栈'
    console.log(box2.innerText);  // ''
    console.log(box3.innerHTML);  // <span style="display: none;">For技术栈</span>
  </script>
</body>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  • 将内容隐藏后,innerText 是获取不到内容的;通过 innerText 获取内容的时候,会触发网页重排(Reflow),也就是重新结算 CSS 样式,所以 textContent 的性能是要好一点的。
内容未完......