跳到主要内容

文本节点

文本节点由 Text 类型表示,包含纯文本内容,或转义以后的 HTML 字符,但不能包含 HTML 代码。

  • nodeType 值为 3
  • nodeName 值为 "#text"
  • nodeValue 值为节点所包含的文本
  • parentNode 值为一个 Element 节点
  • 不包含子节点

访问文本节点

使用 nodeValue 或 data 属性可访问文本节点包含的文本。使用 length 属性可以获取文本的长度,利用该属性可以遍历文本节点的每一个字符。

使用 innerText 属性可以更直接的读取元素文本,但 innerText 不是标准用法,需要考虑浏览器的兼容性。

//获取指定元素包含的文本
// //参数: e 表示指定的元素
// 返回值:返回包含的所有文本,包括子元素包含的文本
function text(e) {
var s = '';
var e = e.childNodes || e;
for (var i = 0; i < e.length; i++) {
s += e[i].nodeType != 1 ? e[i].nodeValue : text(e[i].childNodes);
// 通过递归遍历所有的子节点
}
return s;
}

创建文本节点

document.createTextNode(data);

由于 DOM 操作 的原因,可能出现文本节点不含文本,或者出现两个文本节点的情况。为了避免这种情况,一般在父元素上使用 normalize() 方法,删除空的文本节点,合并相邻的文本节点 。

var element = document.createElement('div');
var textNode = document.createTextNode('hello');
element.appendChild(textNode);
var anotherTextNode = document.createTextNode(' world!');
element.appendChild(anotherTextNode);
document.body.appendChild(element);
alert(element.childNodes.length);
// 2
element.normalize();
alert(element.childNodes.length); // 1
alert(element.firstChild.nodeValue); // 返回 "hello World"

操作文本节点

使用下列方法操作文本节点

  • appendData(string)
  • deleteData(start,length)
  • insertData(start,string)
  • replaceData(start,length,string)
  • splitText(offset) 在 offset 下标位置把一个 Text 节点分割成两个节点
  • substringData(start,length) 从 start 开始位置开始提取 length 个字符

在默认情况下,每个可以包含内容的元素最多只能有一个文本节点,而且必须有内容存在。

读取 HTML 字符串

使用 innerHTML 属性可以返回调用的元素包含的所有子节点对应的 HTML 标记字符串。最初,是 IE 特有属性,但是,后来得到了 HTML 5 的规范,并得到所有浏览器支持。

早期 Mozilla 浏览器的 innerHTML 属性返回值不包含 style 元素。早期 IE 浏览器会被全部使用大写的形式返回元素的字符名称。

插入 HTML 字符串

innerHTML 属性

使用 innerHTML 属性可以根据传入的字符串创建 DOM 片段。然后用这个片段完全代替调用的所有的子节点。设置 innerHTML 属性后,可以像访问文档其它节点一样访问新建的节点。

通过 document.createElement() 和 document.createTextNode() 方法创建表格,代码会非常的长,在一定的情况下,使用 innerHTML 执行更快。

function tableInnerHTML() {
var i,
h = ['<table border="1" width="100%">'];
h.push('<thead>');
h.push(
'<tr><th>id</th><th>yes?</th><th>name</th><th>url</th><th>action</th></tr>',
);

h.push('</thead>');
h.push('<tbody>');
for (var i = 1; i <= 100; i++) {
h.push('<tr><td>');
h.push(i);
h.push('</td><td>');
h.push('And the answer ... is ' + (i % 2 ? 'yes' : 'no'));
h.push('</td><td>');
h.push('My name is #' + i);
h.push('</td><td>');
h.push(
'<a href="https://exmple.org/' +
i +
'.html">https://example.org' +
i +
'.html</a>',
);
h.push('</td><td>');
h.push('<ul>');
h.push('<li><a href="edit.php?id="' + i + '">edit</a></li>');
h.push('<li><a href="delete.php?id=">' + i + '-id001">delete</a></li>');
h.push('</ul>');
h.push('</td>');
h.push('</tr>');
}
h.push('</tbody>');
h.push('<\table>');
document.getElementById('here').innerHTML = h.join('');
}
{
// /* <div id="here"></div> */
}
tableInnerHTML();

使用 innerHTML() 也有很大的限制。例如,在很多浏览器中,通过 innerHTML() 插入的 标记后,并不会执行其中的代码。

实际返回的文本内容会因浏览器而不同。 IE 和 Opera 会把所有元素标签转换为大写,而 Safari 、 Chrome 和 Firefox 则会按照文档源代码的格式返回,包含空格和缩进。因此不要指望不同浏览器的 innerHTML 会返回完全一样的值。

insertAdjacentHTML() 方法

插入 HTML 标记另一种方法就是 insertAdjacentHTML() 方法。这个方法也是最早在 IE 中出现,后来被 HTML 5 采用。

insertAdjacentHTML() 方法有两个参数,第一个是设置插入的位置,第二个参数传入要插入的 HTML 代码。第一个参数必须是下列的值:

  • "beforebegin" 在当前元素之前插入一个紧邻的同辈元素
  • "afterbegin" 在当前元素之下插入一个新的子元素,或在第一个子元素之前插入新的子元素
  • "beforeend" 在当前元素之下插入一个新的子元素,或在最后一个子元素之后再插入一个新的子元素
  • "afterend" 在当前元素之后插入一个紧邻的同辈元素
<style type="text/css">
div {
border: solid 1px red;
margin: 6px;
padding: 6px;
}
h2 {
margin: 6px;
padding: 0;
font-size: 16px;
}
</style>
<div id="box1">
<h2>
insertAdjacentHTML(&quot;beforebegin&quot;, &quot;
<p>beforebegin</p>
&quot;)
</h2>
</div>
<div id="box2">
<h2>
insertAdjacentHTML(&quot;afterbegin&quot;, &quot;
<p>afterbegin</p>
&quot;)
</h2>
</div>
<div id="box3">
<h2>
insertAdjacentHTML(&quot;beforeend&quot;, &quot;
<p>beforeend</p>
&quot;)
</h2>
</div>
<div id="box4">
<h2>
insertAdjacentHTML(&quot;afterend&quot;, &quot;
<p>afterend</p>
&quot;)
</h2>
</div>
document.getElementById("box1").insertAdjacentHTML("beforebegin", "
<p>beforebegin</p>
"); document.getElementById("box2").insertAdjacentHTML("afterbegin", "
<p>afterbegin</p>
"); document.getElementById("box3").insertAdjacentHTML("beforeend", "
<p>beforeend</p>
"); document.getElementById("box4").insertAdjacentHTML("afterend", "
<p>afterend</p>
");

替换 HTML 字符串

outHTML 也是 IE 私有属性,后来被 HTML5 规范,与 innerHTML 一样,但是它会包含元素自身。在读入模式下, outerHTML 返回调用它的元素及所有的子节点的 HTML 标签;在写入模式下, outHTML 会根据指定的 HTML 字符串创建新的 DOM 子树,然后用这个 DOM 子树完全替代调用元素。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta
name="viewport"
content="width=device-width,
initial-scale=1.0"
/>
<title>Document</title>
<style>
li {
border: solid 1px red;
margin: 12px;
}
h2 {
border-bottom: double 3px blue;
}
</style>
</head>
<body>
<h1>单击回答问题</h1>
<ul>
<li>你叫什么?</li>
<li>你喜欢 JS 么?</li>
</ul>
<script>
var ul = document.getElementsByTagName("ul")[0];
var lis = ul.getElementsByTagName("li");
lis[0].onclick = function() { this.innerHTML =
"<h2>我是一个学者<\/h2>" } lis[1].onclick = function()
{ this.outerHTML = "<h2>当然喜欢<\/h2>"
}
</script>
</body>
</html>

在使用 innerHTML 和 outHTML 同时,应删除被替换元素的所有事件处理程序和 javaScript 对象属性。

插入文本

innerText 和 outerText 也是 IE 的私有属性,尚未被 HTML 5 纳入规范,但是却很实用。

innerText 属性

innerText 在指定的元素中插入文本,如果文本中包含 HTML 字符串,将被编码显示。也可以使用该属性读取指定元素包含的全部嵌套信息的文本信息。

Firefox 不支持 innerText ,但支持功能类似的 textContent 属性。 textContent 是 DOM Level 3 规定的一个属性,支持 textContent 属性的浏览器还有 IE9+ 、 Safari 3+ 、 Opera 10+ 、 chrome 。

function getInnerText(element) {
return typeof element.textContent === 'string'
? element.textContent
: element.innerText;
}
function setInnerText(element, text) {
if (typeof element.textContent == 'string') {
element.textContent = text;
} else {
element.innerText = text;
}
}

outerText

outerText 功能与 innerText 类似,但是它覆盖原有元素。

读写文本

innerText 和 outText 也是 IE 的私有属性,但尚未被 HTML5 所纳入规范。