@tiptap/vue-2 知识点笔记-03

10 schema

js 复制代码
{
  schema: {
    cached,
    linebreakReplacement,
    markFromJSON,
    marks,
    nodeFromJSON,
    nodes,
    spec,
    topNodeType,
  },
}

@tiptap/vue-2 中,schema 是基于已加载扩展生成的文档结构规则 ,定义了编辑器支持的节点(如段落、标题、表格)、标记(如加粗、斜体、链接)及其嵌套关系,是编辑器验证和处理内容的核心依据。以下是 schema 相关属性和方法的详细解释及使用示例:

  • schema.cached

    • 类型:Object

    • 功能描述:存储 schema 的缓存数据(如节点/标记的类型映射、解析缓存),用于优化性能,减少重复计算

    • 使用示例:

      javascript 复制代码
      // 查看缓存的节点类型映射(键为节点名称,值为节点类型) 
      console.log('缓存的节点类型:', editor.schema.cached.nodes); 
      // 查看缓存的标记类型映射 
      console.log('缓存的标记类型:', editor.schema.cached.marks); 
      // 示例:从缓存中快速获取"paragraph"节点类型 
      const paragraphType = editor.schema.cached.nodes.paragraph; 
      console.log('段落节点配置:', paragraphType.spec);
  • schema.linebreakReplacement

    • 类型:string

    • 功能描述:定义用于替换换行符的特殊字符串(内部处理用,通常为 \u0001),避免与普通文本冲突

    • 使用示例:

      javascript 复制代码
      // 查看换行符替换字符串 
      console.log('换行符替换标记:', editor.schema.linebreakReplacement); 
      // 示例:处理包含换行的文本时,使用此标记分割 
      const rawText = '第一行\n第二行'; 
      const processedText = rawText.replace(/\n/g, editor.schema.linebreakReplacement); 
      console.log('处理后的文本:', processedText);
  • schema.markFromJSON(json)

    • 类型:Function

    • 功能描述:将 JSON 格式的标记数据转换为 ProseMirror 标记实例(用于解析或恢复标记)

    • 使用示例:

      javascript 复制代码
      // 1. 定义加粗标记的JSON数据 
      const boldMarkJSON = {   
        type: 'bold',   
        attrs: {} // 加粗无额外属性 
        }; 
        // 2. 转换为标记实例 
        const boldMark = editor.schema.markFromJSON(boldMarkJSON); 
        // 3. 使用标记实例(如给文本添加加粗) 
        const textNode = editor.schema.text('加粗文本', [boldMark]); 
        console.log('带加粗标记的文本节点:', textNode);
  • schema.marks

    • 类型:Object

    • 功能描述:存储所有支持的标记类型 (如 bolditaliclink),每个标记类型包含其配置和行为规则

    • 使用示例:

      javascript 复制代码
      // 1. 查看所有支持的标记类型 
      console.log('支持的标记:', Object.keys(editor.schema.marks)); 
      // 如 ["bold", "italic", "link"] 
      // 2. 获取"link"标记的配置(如支持的属性) 
      const linkMark = editor.schema.marks.link; 
      console.log('链接标记支持的属性:', linkMark.spec.attrs); 
      // 如 { href: {}, target: {} } 
      // 3. 检查是否支持特定标记 
      if (editor.schema.marks.strike) {
        console.log('支持删除线标记');
      }
  • schema.nodeFromJSON(json)

    • 类型:Function

    • 功能描述:将 JSON 格式的节点数据转换为 ProseMirror 节点实例(用于解析或恢复节点)

    • 使用示例:

      javascript 复制代码
      // 1. 定义段落节点的JSON数据 
      const paragraphJSON = {   
        type: 'paragraph',   
        content: [     {       type: 'text',       text: '这是一个段落'     }   ] 
      }; 
      // 2. 转换为节点实例 
      const paragraphNode = editor.schema.nodeFromJSON(paragraphJSON); 
      // 3. 插入节点到编辑器 
      editor.commands.insertContent(paragraphNode);
  • schema.nodes

    • 类型:Object

    • 功能描述:存储所有支持的节点类型 (如 docparagraphheadingtable),每个节点类型包含其结构规则(如允许的子节点、属性)

    • 使用示例:

      javascript 复制代码
      // 1. 查看所有支持的节点类型 
      console.log('支持的节点:', Object.keys(editor.schema.nodes)); 
      // 如 ["doc", "paragraph", "heading", "table"] 
      // 2. 获取"heading"节点的配置(如支持的级别) 
      const headingNode = editor.schema.nodes.heading; 
      console.log('标题节点支持的级别:', headingNode.spec.attrs.level.default); 
      // 如 1 
      // 3. 检查节点是否允许特定子节点(如表格是否允许表格行) 
      const tableNode = editor.schema.nodes.table; 
      const tableRowNode = editor.schema.nodes.table_row; 
      const allowsTableRow = tableNode.spec.content.includes(tableRowNode.name); 
      console.log('表格是否允许表格行作为子节点:', allowsTableRow); // 输出 true
  • schema.spec

    • 类型:Object

    • 功能描述:存储 schema 的原始配置(包含节点、标记的完整定义),是构建 schema 的基础数据

    • 使用示例:

      javascript 复制代码
      // 1. 查看 schema 的完整配置 
      console.log('schema 原始配置:', editor.schema.spec); 
      // 2. 获取节点的原始定义(如段落节点的 content 规则) 
      const paragraphSpec = editor.schema.spec.nodes.find(n => n.name === 'paragraph'); 
      console.log('段落节点的内容规则:', paragraphSpec.spec.content); 
      // 如 "inline*"(允许零个或多个 inline 节点) 
      // 3. 获取标记的原始定义(如链接标记的 attrs 规则) 
      const linkSpec = editor.schema.spec.marks.find(m => m.name === 'link'); 
      console.log('链接标记的属性规则:', linkSpec.spec.attrs);
  • schema.topNodeType

    • 类型:NodeType

    • 功能描述:指向文档的根节点类型 (通常为 doc 节点),所有内容都嵌套在根节点下

    • 使用示例:

      javascript 复制代码
      // 1. 获取根节点类型(通常是"doc") 
      const rootNodeType = editor.schema.topNodeType; 
      console.log('根节点类型名称:', rootNodeType.name); // 输出 "doc" 
      // 2. 查看根节点允许的子节点规则(如允许段落、标题等) 
      console.log('根节点允许的子节点:', rootNodeType.spec.content); 
      // 如 "block+"(允许一个或多个 block 节点) 
      // 3. 创建一个空的根节点实例 
      const emptyDoc = rootNodeType.createAndFill(); 
      console.log('空文档节点:', emptyDoc);

10.1 核心作用与使用场景

  1. 内容合法性校验 :通过 schema.nodesschema.marks 检查内容是否符合编辑器规则(如判断能否在表格中插入标题)。
  2. 内容解析与生成 :使用 nodeFromJSONmarkFromJSON 从 JSON 数据恢复文档结构(如加载保存的内容)。
  3. 扩展开发与调试 :通过 schema.spec 查看扩展的底层配置,验证自定义扩展是否正确注册。

例如,在开发自定义粘贴功能时,可通过 schema 检查粘贴的 HTML 节点是否被支持,避免插入非法内容:

javascript 复制代码
// 检查粘贴的节点是否为编辑器支持的节点
function isNodeSupported(nodeName) {
  return Object.keys(editor.schema.nodes).includes(nodeName);
}

// 示例:判断"video"节点是否支持
console.log('是否支持视频节点:', isNodeSupported('video')); // 若未加载视频扩展则输出 false

理解 schema 有助于深入掌握 Tiptap 的内容处理机制,特别是在开发复杂扩展或自定义内容校验逻辑时尤为重要。

11 view

js 复制代码
{
  view: {
    cursorWrapper,
    directPlugins,
    dispatch,
    docView,
    dom,
    domObserver,
    dragging,
    editable,
    focused,
    input,
    lastSelectedViewDesc,
    markCursor,
    mounted,
    nodeViews,
    pluginViews,
    prevDirectPlugins,
    requiresGeckoHackNode,
    state,
    trackWrites,
    _props,
    _root,
    composing,
    isDestroyed,
    props,
    root,
  },
}

@tiptap/vue-2 中,view 是编辑器的可视化视图实例 ,基于 ProseMirror 的 EditorView 封装,负责将文档数据(state)渲染为 DOM 并处理用户交互(如输入、点击、选择)。以下是 view 相关属性的详细解释及使用示例:

  • view.cursorWrapper

    • 类型:HTMLElement

    • 功能描述:包裹光标元素的容器 DOM 节点,用于控制光标显示位置和样式

    • 使用示例:

      javascript 复制代码
      // 修改光标容器的样式(影响光标显示) 
      const cursorWrapper = editor.view.cursorWrapper; 
      if (cursorWrapper) {   
        cursorWrapper.style.zIndex = '100'; 
        // 确保光标在最上层   
        cursorWrapper.style.position = 'relative'; 
      }
  • view.directPlugins

    • 类型:Array<Plugin>

    • 功能描述:直接注册到视图的 ProseMirror 插件列表(不包含扩展间接注册的插件)

    • 使用示例:

      javascript 复制代码
      // 遍历直接注册的插件 
      editor.view.directPlugins.forEach(plugin => {   
        console.log('直接注册的插件:', plugin.key); 
      }); 
      // 检查是否包含历史记录插件 
      const hasHistoryPlugin = editor.view.directPlugins.some(plugin => plugin.key.includes('history') );
  • view.dispatch

    • 类型:Function

    • 功能描述:分发事务(transaction)的核心方法,用于修改编辑器状态(如内容、选区)

    • 使用示例:

      javascript 复制代码
      // 创建一个插入文本的事务 
      const transaction = editor.view.state.tr.insertText('通过dispatch插入的文本'); 
      // 通过view.dispatch执行事务 
      editor.view.dispatch(transaction);
  • view.docView

    • 类型:NodeView

    • 功能描述:文档根节点对应的视图对象,管理整个文档的 DOM 渲染

    • 使用示例:

      javascript 复制代码
      // 获取文档视图的DOM元素 
      const docDom = editor.view.docView.dom; 
      // 修改文档根节点样式 
      docDom.style.maxWidth = '800px'; 
      docDom.style.margin = '0 auto';
  • view.dom

    • 类型:HTMLElement

    • 功能描述:编辑器最外层的 DOM 元素,包含整个编辑区域

    • 使用示例:

      javascript 复制代码
      // 获取编辑器DOM元素 
      const editorDom = editor.view.dom; 
      // 修改编辑器容器样式 
      editorDom.style.border = '1px solid #ddd'; 
      editorDom.style.padding = '16px'; 
      // 监听编辑器容器的点击事件 
      editorDom.addEventListener('click', () => {
        console.log('编辑器区域被点击');
      });
  • view.domObserver

    • 类型:MutationObserver

    • 功能描述:用于监听编辑区域 DOM 变化的观察者实例,同步 DOM 变化到文档状态

    • 使用示例:

      javascript 复制代码
      // 查看DOM观察者的配置 
      console.log('DOM观察者配置:', editor.view.domObserver.options); 
      // 临时暂停DOM观察 
      editor.view.domObserver.disconnect(); 
      // 执行手动DOM修改后重新启动观察 
      setTimeout(() => {   
        editor.view.domObserver.observe(editor.view.dom, {     
          childList: true,     
          subtree: true   
        }); 
      }, 1000);
  • view.dragging

    • 类型:Object|null

    • 功能描述:存储当前拖放操作的状态(如拖拽的节点类型、位置),拖放时为对象,否则为 null

    • 使用示例:

      javascript 复制代码
      // 监听拖放状态变化 
      editor.on('transaction', () => {   
        if (editor.view.dragging) {     
          console.log('正在拖拽:', editor.view.dragging.type.name);   
        } else {     
          console.log('拖放结束');   
        } 
      });
  • view.editable

    • 类型:boolean

    • 功能描述:标记当前视图是否可编辑(与编辑器 editable 状态同步)

    • 使用示例:

      javascript 复制代码
      // 查看当前可编辑状态 
      console.log('视图是否可编辑:', editor.view.editable); 
      // 动态切换可编辑状态(建议使用editor.setEditable()) 
      editor.view.setEditable(false); 
      // 底层方法
  • view.focused

    • 类型:boolean

    • 功能描述:标记视图是否处于聚焦状态(与编辑器 isFocused 状态同步)

    • 使用示例:

      javascript 复制代码
      // 根据聚焦状态修改样式 
      if (editor.view.focused) {   
        editor.view.dom.classList.add('focused'); 
      } else {   
        editor.view.dom.classList.remove('focused'); 
      }
  • view.input

    • 类型:HTMLElement

    • 功能描述:用于接收输入的底层 DOM 元素(通常是一个 contenteditable 元素)

    • 使用示例:

      javascript 复制代码
      // 获取输入元素 
      const inputEl = editor.view.input; 
      // 禁用浏览器默认拼写检查 
      inputEl.spellcheck = false; 
      // 修改输入元素的光标样式 
      inputEl.style.caretColor = '#2196f3'; 
  • view.lastSelectedViewDesc

    • 类型:NodeViewDesc|null

    • 功能描述:记录最后选中的节点视图描述,包含节点类型和位置信息

    • 使用示例:

      javascript 复制代码
      // 获取最后选中的节点信息 
      const lastSelected = editor.view.lastSelectedViewDesc; 
      if (lastSelected) {   
        console.log('最后选中的节点类型:', lastSelected.node.type.name);   
        console.log('节点位置:', lastSelected.pos); 
      }
  • view.markCursor

    • 类型:HTMLElement|null

    • 功能描述:标记光标位置的 DOM 元素(用于特定光标样式或定位)

    • 使用示例:

      javascript 复制代码
      // 修改标记光标的样式 
      if (editor.view.markCursor) {   
        editor.view.markCursor.style.width = '2px';   
        editor.view.markCursor.style.backgroundColor = '#ff5722'; 
      } 
  • view.mounted

    • 类型:boolean

    • 功能描述:标记视图是否已挂载到 DOM 上

    • 使用示例:

      javascript 复制代码
      // 确保视图挂载后执行DOM操作 
      if (editor.view.mounted) {   
        initEditorScroll(); 
        // 初始化滚动位置 
      } else {   
        // 监听挂载事件 
        editor.on('create', initEditorScroll); 
      }
  • view.nodeViews

    • 类型:Object

    • 功能描述:存储所有自定义节点视图的映射(键为节点名称,值为节点视图类)

    • 使用示例:

      javascript 复制代码
      // 查看所有自定义节点视图 
      console.log('自定义节点视图:', Object.keys(editor.view.nodeViews)); 
      // 获取代码块节点的视图 
      const codeBlockView = editor.view.nodeViews.code_block; 
      if (codeBlockView) {   
        console.log('代码块视图类:', codeBlockView); 
      }
  • view.pluginViews

    • 类型:Array<Object>

    • 功能描述:存储插件创建的视图实例(如工具栏、菜单等插件生成的 UI 元素)

    • 使用示例:

      javascript 复制代码
      // 遍历插件视图 
      editor.view.pluginViews.forEach(pluginView => {   
        // 隐藏特定插件的视图(如历史记录插件的UI)   
        if (pluginView.plugin.key.includes('history')) {     
          pluginView.dom.style.display = 'none';   
        } 
      }); 
  • view.prevDirectPlugins

    • 类型:Array<Plugin>

    • 功能描述:上一次更新前的直接插件列表(用于插件变更检测)

    • 使用示例:

      javascript 复制代码
      // 检测直接插件是否有变化 
      const pluginsChanged = editor.view.directPlugins.length !== editor.view.prevDirectPlugins.length; 
      if (pluginsChanged) {   
        console.log('直接插件列表已变更'); 
      }
  • view.requiresGeckoHackNode

    • 类型:boolean

    • 功能描述:标记是否需要针对 Firefox 浏览器的特殊节点处理(内部兼容性优化)

    • 使用示例:

      javascript 复制代码
      // 针对Firefox的特殊处理 
      if (editor.view.requiresGeckoHackNode) {   
        console.log('当前环境需要Firefox兼容性处理');   
        // 添加额外的样式修复   
        editor.view.dom.classList.add('gecko-fix'); 
      }
  • view.state

    • 类型:EditorState

    • 功能描述:编辑器当前的状态对象,包含文档内容、选区、历史记录等核心数据

    • 使用示例:

      javascript 复制代码
      // 获取当前文档内容(ProseMirror文档对象) 
      const doc = editor.view.state.doc; 
      console.log('文档内容长度:', doc.nodeSize); 
      // 获取当前选区 
      const selection = editor.view.state.selection; 
      console.log('选区范围:', selection.from, '-', selection.to);
  • view.trackWrites

    • 类型:Function

    • 功能描述:用于跟踪 DOM 写入操作的工具方法(内部性能优化用)

    • 使用示例:

      javascript 复制代码
      // 跟踪批量DOM修改 
      editor.view.trackWrites(() => {   
        // 执行多个DOM操作   
        editor.view.dom.style.padding = '20px';   
        editor.view.input.style.fontSize = '16px';
      });
  • view._props

    • 类型:Object

    • 功能描述:视图内部存储的属性配置(包含初始化时的 editorProps 等)

    • 使用示例:

      javascript 复制代码
      // 查看内部属性配置 
      console.log('视图内部属性:', editor.view._props); 
      // 获取自定义键盘事件处理配置 
      const keyHandlers = editor.view._props.handleKeyDown;
  • view._root

    • 类型:HTMLElement

    • 功能描述:视图内部的根 DOM 元素(通常与 view.dom 一致或为其容器)

    • 使用示例:

      javascript 复制代码
      // 修改内部根元素样式 
      editor.view._root.style.backgroundColor = '#f9f9f9';
  • view.composing

    • 类型:boolean

    • 功能描述:标记当前是否处于输入法组合输入状态(如中文拼音输入过程中)

    • 使用示例:

      javascript 复制代码
      // 避免在组合输入时执行自动保存 
      editor.on('update', () => {   
        if (!editor.view.composing) {     
          saveContent(); 
          // 仅在非组合输入状态下保存   
        } 
      });
  • view.isDestroyed

    • 类型:boolean

    • 功能描述:标记视图是否已销毁

    • 使用示例:

      javascript 复制代码
      // 销毁前清理资源 
      if (!editor.view.isDestroyed) {   
        editor.view.destroy(); // 手动销毁视图 
      }
  • view.props

    • 类型:Object

    • 功能描述:视图的公开属性配置(与 _props 类似,但经过处理)

    • 使用示例:

      javascript 复制代码
      // 获取视图的属性配置(如编辑器是否可编辑) 
      console.log('视图公开属性:', editor.view.props.editable); 
  • view.root

    • 类型:HTMLElement

    • 功能描述:视图的根 DOM 元素(与 view.dom 一致,为公开访问别名)

    • 使用示例:

      javascript 复制代码
      // 滚动到编辑器顶部 
      editor.view.root.scrollTop = 0;
  1. 底层视图控制view 直接对应 ProseMirror 的 EditorView,是编辑器 UI 渲染和用户交互的核心,大部分属性用于底层控制,日常开发中建议优先使用 Tiptap 封装的高层 API(如 editor.setContent()editor.focus())。
  2. DOM 操作场景 :当需要直接修改编辑区域的 DOM 样式或行为(如自定义光标、容器样式)时,可通过 view.domview.input 等属性操作。
  3. 状态同步view.state 包含编辑器的实时状态,可用于获取选区、文档结构等底层数据,但修改状态需通过 view.dispatch() 分发事务,而非直接修改 state

例如,在实现自定义光标样式时,可结合 view.focusedview.cursorWrapper 动态调整:

javascript 复制代码
// 监听聚焦状态变化,更新光标样式
editor.on('focus', () => {
  if (editor.view.cursorWrapper) {
    editor.view.cursorWrapper.style.backgroundColor = '#2196f3';
  }
});

editor.on('blur', () => {
  if (editor.view.cursorWrapper) {
    editor.view.cursorWrapper.style.backgroundColor = '#ccc';
  }
});

理解 view 的属性有助于解决复杂的 UI 定制和交互问题,但需注意直接操作底层属性可能影响编辑器的稳定性,建议在确有必要时使用。

12 $doc

js 复制代码
{
  $doc: {
    actualDepth,
    currentNode,
    editor,
    isBlock,
    resolvedPos,
    after,
    attributes,
    before,
    children,
    content,
    depth,
    element,
    firstChild,
    from,
    lastChild,
    name,
    node,
    parent,
    pos,
    range,
    size,
    textContent,
    to,
  },
}

@tiptap/vue-2 中,$doc 是一个文档查询工具对象 ,封装了对编辑器当前文档结构、节点信息及位置关系的查询能力,基于 ProseMirror 的文档模型提供高层级 API,方便开发者快速获取文档内容和节点状态。以下是 $doc 所有属性的详细解释及使用示例:

  • $doc.actualDepth

    • 类型:number

    • 功能描述:获取当前选中节点在文档树中的「实际深度」(考虑嵌套层级,如表格单元格中的段落深度更高)

    • 使用示例:

      javascript 复制代码
      // 获取当前选中节点的实际深度 
      console.log('当前节点实际深度:', editor.$doc.actualDepth); 
      // 示例:判断是否为深层嵌套节点(如表格内的列表项) 
      if (editor.$doc.actualDepth > 3) {   
        console.log('当前节点处于深层嵌套结构中'); 
      }
  • $doc.currentNode

    • 类型:Node(ProseMirror)

    • 功能描述:获取「当前选中的节点」(光标所在或选中范围的主节点,如段落、标题)

    • 使用示例:

      javascript 复制代码
      // 获取当前选中节点 
      const currentNode = editor.$doc.currentNode; 
      if (currentNode) {   
        console.log('当前节点类型:', currentNode.type.name); 
        // 如"paragraph"、"heading"   
        console.log('当前节点文本:', currentNode.textContent); 
      }
  • $doc.editor

    • 类型:Editor

    • 功能描述:指向当前关联的编辑器实例,用于在文档查询中快速访问编辑器方法

    • 使用示例:

      javascript 复制代码
      // 通过$doc访问编辑器实例并执行命令 
      editor.$doc.editor.commands.bold(); 
      // 等价于 
      editor.commands.bold() 
      // 获取编辑器内容 HTML 
      console.log('文档HTML:', editor.$doc.editor.getHTML());
  • $doc.isBlock

    • 类型:boolean

    • 功能描述:判断当前选中节点是否为「块级节点」(如段落、标题、表格,而非行内文本、标记)

    • 使用示例:

      javascript 复制代码
      // 检查当前节点是否为块级节点 
      if (editor.$doc.isBlock) {   
        console.log('当前选中的是块级节点');   
        // 对块级节点执行操作(如添加缩进)   
        editor.commands.indent(); 
      } else {   
        console.log('当前选中的是行内元素或标记'); 
      }
  • $doc.resolvedPos

    • 类型:ResolvedPos

    • 功能描述:光标或选区起始位置的「解析位置对象」,包含位置在文档树中的详细层级信息

    • 使用示例:

      javascript 复制代码
      // 获取解析位置对象 
      const resolvedPos = editor.$doc.resolvedPos; 
      if (resolvedPos) {   
        console.log('位置深度:', resolvedPos.depth); // 位置所在层级   
        console.log('父节点类型:', resolvedPos.parent.type.name); // 父节点类型 
      }
  • $doc.after

    • 类型:number

    • 功能描述:获取当前节点「结束位置的索引」(在文档全局范围内的结束偏移量)

    • 使用示例:

      javascript 复制代码
      // 获取当前节点的结束位置索引 
      console.log('当前节点结束位置:', editor.$doc.after); 
      // 示例:选中当前节点之后的内容 
      editor.commands.setTextSelection({   
        from: editor.$doc.after,   
        to: editor.$doc.after + 5 // 选中结束位置后5个字符 
      });
  • $doc.attributes

    • 类型:Object

    • 功能描述:获取当前节点的「属性集合」(如标题的 level、链接的 href 等)

    • 使用示例:

      javascript 复制代码
      // 获取当前节点的属性 
      const attrs = editor.$doc.attributes; 
      // 示例:若当前是标题节点,获取级别 
      if (editor.$doc.name === 'heading') {   
        console.log('标题级别:', attrs.level); // 如1、2、3 
      } 
      // 示例:若当前是链接节点,获取URL 
      if (editor.$doc.name === 'link') {
        console.log('链接地址:', attrs.href);
      }
  • $doc.before

    • 类型:number

    • 功能描述:获取当前节点「起始位置的索引」(在文档全局范围内的起始偏移量)

    • 使用示例:

      javascript 复制代码
      // 获取当前节点的起始位置索引 
      console.log('当前节点起始位置:', editor.$doc.before); 
      // 示例:在当前节点前插入内容 
      editor.commands.insertContentAt(editor.$doc.before, '<p>插入到当前节点前</p>');
  • $doc.children

    • 类型:Array<Node>

    • 功能描述:获取当前节点的「直接子节点列表」(如表格的子节点是表格行,列表的子节点是列表项)

    • 使用示例:

      javascript 复制代码
      // 获取当前节点的直接子节点 
      const children = editor.$doc.children; 
      console.log('当前节点子节点数量:', children.length); 
      // 示例:遍历表格的所有行(若当前节点是表格) 
      if (editor.$doc.name === 'table') {   
        children.forEach((row, index) => {     
          console.log(`第${index+1}行单元格数量:`, row.childCount);   
        }); 
      }
  • $doc.content

    • 类型:Content

    • 功能描述:获取当前节点的「内容容器对象」(包含子节点的迭代器和操作方法)

    • 使用示例:

      javascript 复制代码
      // 获取当前节点的内容容器 
      const content = editor.$doc.content; 
      // 迭代子节点并输出文本 
      content.forEach(node => {   
        console.log('子节点文本:', node.textContent); 
      }); 
      // 检查内容是否为空 
      console.log('当前节点内容是否为空:', content.size === 0);
  • $doc.depth

    • 类型:number

    • 功能描述:获取当前节点在文档树中的「层级深度」(根节点 doc 为0,其子节点为1,以此类推)

    • 使用示例:

      javascript 复制代码
      // 获取当前节点的层级深度 
      console.log('当前节点层级深度:', editor.$doc.depth); 
      // 示例:限制嵌套层级(如列表最多嵌套2层) 
      if (editor.$doc.depth > 2 && editor.$doc.name === 'listItem') {   
        console.log('已达到最大嵌套层级'); 
      }
  • $doc.element

    • 类型:HTMLElement|null

    • 功能描述:获取当前节点对应的「DOM 元素」(若节点已渲染到页面)

    • 使用示例:

      javascript 复制代码
      // 获取当前节点的DOM元素 
      const nodeEl = editor.$doc.element; 
      if (nodeEl) {   
        // 修改当前节点的DOM样式   
        nodeEl.style.backgroundColor = '#f0f0f0';   
        nodeEl.style.padding = '8px'; 
      }
  • $doc.firstChild

    • 类型:Node|null

    • 功能描述:获取当前节点的「第一个直接子节点」(如段落的第一个子节点可能是文本节点)

    • 使用示例:

      javascript 复制代码
      // 获取第一个子节点 
      const firstChild = editor.$doc.firstChild; 
      if (firstChild) {   
        console.log('第一个子节点类型:', firstChild.type.name);   
        console.log('第一个子节点文本:', firstChild.textContent); 
      }
  • $doc.from

    • 类型:number

    • 功能描述:获取当前选区的「起始位置索引」(全局偏移量,与 before 不同,from 是选区起始而非节点起始)

    • 使用示例:

      javascript 复制代码
      // 获取选区起始位置 
      console.log('选区起始:', editor.$doc.from); 
      // 示例:获取选区内的文本 
      const selectionText = editor.getHTML({   
        from: editor.$doc.from,   
        to: editor.$doc.to 
      }); 
      console.log('选区内的文本:', selectionText);
  • $doc.lastChild

    • 类型:Node|null

    • 功能描述:获取当前节点的「最后一个直接子节点」

    • 使用示例:

      javascript 复制代码
      // 获取最后一个子节点 
      const lastChild = editor.$doc.lastChild; 
      if (lastChild) {   
        console.log('最后一个子节点类型:', lastChild.type.name);   
        // 在最后一个子节点后插入内容   
        editor.commands.insertContentAfter(lastChild, '<p>插入到最后</p>'); 
      }
  • $doc.name

    • 类型:string

    • 功能描述:获取当前节点的「类型名称」(如 paragraphheadingtablelistItem

    • 使用示例:

      javascript 复制代码
      // 获取当前节点类型名称 
      const nodeName = editor.$doc.name; 
      console.log('当前节点类型:', nodeName); 
      // 示例:根据节点类型执行不同操作 
      switch (nodeName) {   
        case 'heading':     
          console.log('当前是标题节点');     
          break;   
        case 'table':     
          console.log('当前是表格节点');     
          break;   
        default:     
          console.log('其他节点类型'); 
      } 
  • $doc.node

    • 类型:Node(ProseMirror)

    • 功能描述:获取当前节点的「原始 ProseMirror 节点对象」(包含完整的节点数据和方法)

    • 使用示例:

      javascript 复制代码
      // 获取原始节点对象 
      const node = editor.$doc.node; 
      // 查看节点的完整数据 
      console.log('节点类型:', node.type.name); 
      console.log('节点属性:', node.attrs); 
      console.log('节点大小:', node.nodeSize); 
      // 检查节点是否包含特定标记(如加粗) 
      const hasBold = node.marks.some(mark => mark.type.name === 'bold'); 
      console.log('节点是否包含加粗标记:', hasBold);
  • $doc.parent

    • 类型:Node|null

    • 功能描述:获取当前节点的「父节点」(如列表项的父节点是有序/无序列表)

    • 使用示例:

      javascript 复制代码
      // 获取父节点 
      const parentNode = editor.$doc.parent; 
      if (parentNode) {   
        console.log('父节点类型:', parentNode.type.name);   
        // 示例:若当前是列表项,获取列表类型(有序/无序)   
        if (editor.$doc.name === 'listItem') {     
          console.log('列表类型:', parentNode.type.name); 
          // 如"orderedList"或"bulletList"   
        } 
      }
  • $doc.pos

    • 类型:number

    • 功能描述:获取当前节点在文档中的「起始位置索引」(与 before 一致,为节点的全局偏移量)

    • 使用示例:

      javascript 复制代码
      // 获取当前节点的起始位置 
      console.log('当前节点起始位置:', editor.$doc.pos); 
      // 示例:在当前节点起始位置插入内容 
      editor.commands.insertContentAt(editor.$doc.pos, '<p>插入到节点开始处</p>');
  • $doc.range

    • 类型:{ from: number, to: number }

    • 功能描述:获取当前节点的「完整范围」(from 为起始位置,to 为结束位置)

    • 使用示例:

      javascript 复制代码
      // 获取当前节点的范围 
      const { from, to } = editor.$doc.range; 
      console.log('当前节点范围:', from, '-', to); 
      // 示例:选中整个当前节点 
      editor.commands.setTextSelection({ from, to });
  • $doc.size

    • 类型:number

    • 功能描述:获取当前节点的「大小」(ProseMirror 内部计算的节点长度,包含开始和结束标记)

    • 使用示例:

      javascript 复制代码
      // 获取当前节点的大小 
      console.log('当前节点大小:', editor.$doc.size); 
      // 示例:判断节点是否为空(大小为2表示仅包含开始和结束标记,无内容) 
      if (editor.$doc.size === 2) {   
        console.log('当前节点为空'); 
      }
  • $doc.textContent

    • 类型:string

    • 功能描述:获取当前节点的「纯文本内容」(不含任何格式标记)

    • 使用示例:

      javascript 复制代码
      // 获取当前节点的纯文本 
      console.log('当前节点文本:', editor.$doc.textContent); 
      // 示例:统计当前节点的字符数 
      const charCount = editor.$doc.textContent.length; 
      console.log('当前节点字符数:', charCount);
  • $doc.to

    • 类型:number

    • 功能描述:获取当前选区的「结束位置索引」(全局偏移量,与 after 不同,to 是选区结束而非节点结束)

    • 使用示例:

      javascript 复制代码
      // 获取选区结束位置 
      console.log('选区结束:', editor.$doc.to); 
      // 示例:删除选区内的内容 
      editor.commands.deleteRange({ 
        from: editor.$doc.from, 
        to: editor.$doc.to 
      });
  1. 节点信息查询$doc 提供了从当前选区快速定位节点的能力,通过 currentNodenameattributes 等属性可获取节点类型、属性和内容,适合根据节点类型动态调整工具栏或执行操作(如表格节点显示表格操作按钮)。
  2. 位置计算beforeafterfromto 等属性提供了节点和选区的精确位置索引,结合 insertContentAt 等命令可实现精准的内容插入或修改。
  3. 层级分析depthactualDepthparent 等属性用于分析节点在文档树中的嵌套关系,适合处理复杂结构(如限制列表嵌套层级、表格内节点操作)。

例如,在开发「根据当前节点类型显示不同工具栏」的功能时,可使用 $doc.name 实现:

javascript 复制代码
// 根据当前节点类型动态渲染工具栏
function renderToolbar() {
  const nodeName = editor.$doc.name;
  const toolbar = document.getElementById('toolbar');
  
  // 表格节点显示表格操作按钮
  if (nodeName === 'table') {
    toolbar.innerHTML = '<button id="add-row">添加行</button>';
    document.getElementById('add-row').addEventListener('click', () => {
      editor.commands.addRowAfter();
    });
  } 
  // 标题节点显示级别调整按钮
  else if (nodeName === 'heading') {
    toolbar.innerHTML = '<button id="level-up">升级</button>';
    document.getElementById('level-up').addEventListener('click', () => {
      const currentLevel = editor.$doc.attributes.level;
      if (currentLevel > 1) {
        editor.commands.setHeading({ level: currentLevel - 1 });
      }
    });
  }
}

// 选区变化时更新工具栏
editor.on('selectionUpdate', renderToolbar);

$doc 是 Tiptap 提供的高效文档查询工具,尤其适合需要根据当前编辑上下文动态调整功能的场景,减少了直接操作 ProseMirror 底层 API 的复杂度。

相关推荐
丘耳19 小时前
@tiptap/vue-2 知识点笔记-05
前端·javascript·vue.js
m0_6161884919 小时前
使用el-table实现行内编辑功能
前端·javascript·vue.js
Mintopia19 小时前
🧬 AIGC 内容溯源技术:Web 平台如何识别 AI 生成内容?
前端·javascript·aigc
.NET修仙日记19 小时前
jQuery面试题精选:从基础到高级
前端·javascript·jquery
Mintopia19 小时前
⚙️ Next.js 缓存 + 分页优化:让你的页面速度快得像量子比特 🧠✨
前端·全栈·next.js
玲小珑19 小时前
LangChain.js 完全开发手册(十五)实战综合项目一:智能文档处理系统
前端·langchain·ai编程
午安~婉19 小时前
硅谷甄选(续2)首页
java·前端·javascript
NULL Not NULL19 小时前
Vue 前端面试题(含答案)大全 v2025
前端·javascript·vue.js
苏州第一深情19 小时前
终结加班眼酸?明基RD280U测评:程序员的双倍快乐,竟是4K护眼大屏给的!
前端·后端