XML DOM – Text 对象

XML DOM – Text 对象(文本节点)

Text 是 XML DOM 中最常见的节点类型之一,代表元素或属性中的纯文本内容
它继承自 CharacterData,又被 CDATASection 继承。

1. 基本信息

项目值 / 说明
nodeType3(Node.TEXT_NODE
nodeName始终为 "#text"
nodeValue文本内容(可读写)
textContent与 nodeValue 完全等价
data与 nodeValue 完全等价(CharacterData 接口)
length文本字符数量(UTF-16 代码单元长度)
parentNode通常是 Element 或 Attr(属性值也是 Text 节点)

2. 重要方法(全部来自 CharacterData)

方法功能常用度
appendData(text)在末尾追加文本★★
deleteData(offset, count)删除从 offset 开始的 count 个字符
insertData(offset, text)在 offset 位置插入文本
replaceData(offset, count, text)替换指定范围的文本★★
substringData(offset, count)提取子字符串(不修改原文本)★★★
splitText(offset)关键!将当前 Text 节点从 offset 处劈成两个 Text 节点★★★★★
wholeText只读属性:返回当前节点及所有相邻连续 Text 节点的合并文本★★★★★

3. 核心实战方法:splitText() —— DOM 操作的“神技”

<p>hello <b>world</b> !</p>

假设我们要只把 “world” 包上 ,但不能直接操作中间的文本,必须先拆分:

const p = doc.querySelector("p");
const textNode = p.firstChild;        // "hello "
const rest = textNode.splitText(6);   // 从第6个字符开始切分("hello " 之后)

// 现在文档结构变成:
// Text("hello ") + Text("world !")

const b = doc.createElement("b");
b.textContent = "world";              // 或 b.appendChild(rest.splitText(5))

p.insertBefore(b, rest);              // 在剩余文本前插入 <b>
rest.splitText(5);                    // 把 " !" 再切出来(可选)

// 最终得到: <p>hello <b>world</b> !</p>

这就是所有富文本编辑器(包括浏览器内置的 document.execCommandcontenteditable)实现插入标签的底层原理。

4. wholeText —— 解决“多个相邻 Text 节点”问题

XML 序列化或某些操作会产生连续的 Text 节点:

elem.appendChild(doc.createTextNode("Hello"));
elem.appendChild(doc.createTextNode(" "));
elem.appendChild(doc.createTextNode("World"));

此时然通过 elem.textContentelem.firstChild.wholeText 都能拿到完整文本:

console.log(elem.textContent);     // "Hello World"
console.log(elem.firstChild.wholeText);  // 同上,更高效

5. 创建与添加文本的正确姿势

// 推荐方式(自动转义 < > &)
element.textContent = "价格 < 100 元,且 > 50 元";   // 安全!

// 等价于:
element.appendChild(document.createTextNode("价格 < 100 元,且 > 50 元"));

// 错误示范(会变成真实标签):
element.innerHTML = "价格 < 100 元";   // 在 XML 中极度危险!

6. Text vs CDATASection(重点区别)

项目Text(普通文本节点)CDATASection(CDATA 节点)
nodeType34
nodeName“#text”“#cdata-section”
是否转义是(< 变成 <)否(原样输出)
创建方式document.createTextNode()document.createCDATASection()
典型使用场景普通内容包含大量 <、>、&、脚本、XML 示例代码等

示例:

const cdata = doc.createCDATASection(`
    <script>
      if (a < b && b > c) {
        alert("Hello <world>");
      }
    </script>
`);

doc.documentElement.appendChild(cdata);
// 序列化后原样输出,不会被转义

7. 常见坑 & 注意事项

坑点正确做法
直接用 innerHTML 设置 XML 内容绝对禁止!会破坏 XML 结构
以为 childNodes 只包含元素Text 节点、注释、处理指令都在里面
修改 text.nodeValue 后没反应某些旧 IE 需要先 normalize() 再改
多个连续 Text 节点导致样式/事件异常用 node.normalize() 合并相邻文本节点
// 合并相邻文本节点(推荐在操作完成后调用)
element.normalize();

// 反之:禁止合并(某些编辑器需要保持拆分状态)
element.firstChild.splitText(0); // 制造两个空文本节点阻止合并

8. 总结一览表

特性Text 节点推荐操作方式
内容是否转义日常文本用 Text
包含大量 < > &会被转义改用 CDATASection
获取完整文本.wholeText 或 .textContent优先用 wholeText
拆分文本插入标签splitText(offset)富文本编辑核心技术
合并相邻文本parent.normalize()操作完成后建议调用

一句话结论

XML DOM 中 90% 的实际内容都存在 Text 节点里,掌握 createTextNodesplitTextwholeTextnormalize 四个关键点,你就掌握了 XML/HTML 文本操作的全部底层原理。

文章已创建 2732

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部