tiptap 节点位置
引言
节点位置(简称 NodePos
)是 Tiptap 2.2.0 引入的一个新概念。它们用于描述节点的特定位置,包括其子节点、父节点以及方便在它们之间导航的方式。这些概念深受 DOM 的启发,并基于 Prosemirror 的 ResolvedPos 实现。
使用方法
创建新的 节点位置 最简单的方法是在编辑器实例上使用辅助函数。这样可以确保始终使用正确的编辑器实例,并直接访问 API。
// 在此处设置你的编辑器
// 获取外层文档节点的 NodePosition
const $doc = editor.$doc;
// 获取当前文档中所有类型为 'heading' 的节点
const $headings = editor.$nodes("heading");
// 过滤属性
const $h1 = editor.$nodes("heading", { level: 1 });
// 直接选择节点
const $firstHeading = editor.$node("heading", { level: 1 });
// 如果不知道类型但知道想要操作的位置,可以通过 $pos 方法创建一个新的 NodePos
const $myCustomPos = editor.$pos(30);
你也可以自己创建 NodePos 实例:
// 需要有一个编辑器实例和你想映射到的位置
const myNodePos = new NodePos(100, editor);
用 NodePos 可以做什么?
你可以像浏览器的文档 DOM 一样使用 NodePos 来遍历文档。可以访问父节点、子节点和兄弟节点。以下是使用 codeBlock
节点的一个示例:
// 获取文档中的第一个 codeBlock 节点
const $codeBlock = editor.$node("codeBlock");
// 获取 codeBlock 节点前的 NodePosition
const $previousItem = $codeBlock.before;
// 更新内容
$previousItem.content = "<p>更新后的内容</p>";
如果你熟悉 DOM,以下示例应该很直观:
// 从文档中获取一个无序列表
const $bulletList = editor.$node("bulletList");
// 从无序列表中获取所有列表项
const $listItems = $bulletList.querySelectorAll("listItem");
// 获取最后一个列表项
const $lastListItem = $listItems[0];
// 在最后一个列表项后插入新的列表项
editor.commands.insertContentAt($lastListItem.after, "<li>新项目</li>");
API
NodePos 类
这是你将主要使用的类,用于描述节点的特定位置及其相关关系。它支持向上或向下遍历,以及设置属性等操作。
方法
constructor
参数
pos
:你想映射到的位置editor
:要使用的编辑器实例
返回值 NodePos
const myNodePos = new NodePos(100, editor);
closest
返回当前 NodePos 向上查找的最近匹配的 NodePos。如果没有找到匹配项,则返回 null
。
返回值 NodePos | null
const closest = myNodePos.closest("bulletList");
querySelector
向下查找第一个匹配的 NodePos。如果没有找到匹配项,则返回 null
。可以通过第二个属性过滤。
返回值 NodePos | null
const firstHeading = myNodePos.querySelector("heading");
const firstH1 = myNodePos.querySelector("heading", { level: 1 });
querySelectorAll
向下查找所有匹配的 NodePos。如果没有找到匹配项,则返回一个空数组。同样可以使用第二个属性过滤。
返回值 Array<NodePos>
const headings = myNodePos.querySelectorAll("heading");
const h1s = myNodePos.querySelectorAll("heading", { level: 1 });
setAttributes
为当前 NodePos 设置属性。
返回值 NodePos
myNodePos.setAttributes({ level: 1 });
属性
node
当前 NodePos 对应的 Prosemirror 节点。
返回值 Node
const node = myNodePos.node;
node.type.name; // 'paragraph'
element
当前 NodePos 对应的 DOM 元素。
返回值 Element
const element = myNodePos.element;
element.tagName; // 'P'
content
NodePosition 的内容,可以设置为新的值来更新节点内容。
返回值 string
const content = myNodePos.content;
myNodePos.content = "<p>更新后的内容</p>";
attributes
NodePosition 的属性。
返回值 Object
const attributes = myNodePos.attributes;
attributes.level; // 1
textContent
NodePosition 的文本内容。
返回值 string
const textContent = myNodePos.textContent;
depth
NodePosition 的深度。
返回值 number
const depth = myNodePos.depth;
pos
NodePosition 的位置。
返回值 number
const pos = myNodePos.pos;
size
NodePosition 的大小。
返回值 number
const size = myNodePos.size;
from
NodePosition 的起始位置。
返回值 number
const from = myNodePos.from;
to
NodePosition 的结束位置。
返回值 number
const to = myNodePos.to;
range
NodePosition 的范围。
返回值 number
const range = myNodePos.range;
parent
NodePosition 的父 NodePos。
返回值 NodePos
const parent = myNodePos.parent;
before
NodePosition 前的 NodePos。如果没有前一个 NodePos,则返回 null
。
返回值 NodePos | null
const before = myNodePos.before;
after
NodePosition 后的 NodePos。如果没有后一个 NodePos,则返回 null
。
返回值 NodePos | null
const after = myNodePos.after;
children
NodePosition 的子 NodePos 实例。
返回值 Array<NodePos>
const children = myNodePos.children;
firstChild
NodePosition 的第一个子 NodePos。如果没有子节点,则返回 null
。
返回值 NodePos | null
const firstChild = myNodePos.firstChild;
lastChild
NodePosition 的最后一个子 NodePos。如果没有子节点,则返回 null
。
返回值 NodePos | null
const lastChild = myNodePos.lastChild;