---
title: "常见问题"
description: "关于 Tiptap 的常见问题，这是一个无头编辑器框架。"
canonical_url: "https://tiptap.zhcndoc.com/guides/faq"
---

# 常见问题

关于 Tiptap 的常见问题，这是一个无头编辑器框架。

## 当我将编辑器的内容复制到文本框时，得到了一堆换行符

在 Tiptap 中，默认情况下，剪贴板文本序列化器设置为在段落之间生成 2 个换行符（就像你在 Markdown 中所做的那样）。

所以你粘贴的内容看起来是这样的：

```text
这是一个段落。

这是另一个段落。
```

而你可能希望它看起来是这样的（段落之间没有额外换行符）：

```text
这是一个段落。
这是另一个段落。
```

要实现这一点，你需要将 `clipboardTextSerializer` 更改为使用单个换行符而不是两个。

像这样：

```js
new Editor({
  // 其他选项
  coreExtensionOptions: {
    clipboardTextSerializer: {
      blockSeparator: '\n',
    },
  },
})
```

这将使剪贴板序列化器使用单个换行符作为块之间的分隔符。

## 我的拖放功能无法正常工作

一些库，比如 `react-dnd` 或 `react-beautiful-dnd` 可能会通过全局注册干扰 Tiptap 的拖放功能。\
如果你正在使用这些库中的一个，你可能需要禁用它们（或者至少限制它们监听的元素），以使编辑器的拖放功能正常工作。

## 为什么同时有 `parseHTML` 和 `renderHTML`

`parseHTML` 和 `renderHTML` 可以被视为相反的操作：

- `parseHTML`: HTML -> JSON，将 HTML 表示解析为 JSON。
- `renderHTML`: JSON -> HTML，将 JSON 表示输出为 HTML 以在编辑器中呈现。

这使得 Tiptap 能够在内容表示上非常灵活。你可以将内容定义为 JSON，然后将其渲染为 HTML，或你可以将内容定义为 HTML，然后将其解析为 JSON。

此外，`parseHTML` 和 `renderHTML` 也可以在不同的上下文中使用：\
`renderHTML` 在 *复制事件* 中使用，因为你从编辑器中复制的内容需要序列化为 HTML 以进入剪贴板。\
`parseHTML` 在 *粘贴事件* 中使用，因为你剪贴板中的 HTML 被序列化为 HTML，需要解析为 JSON。

在初次渲染时，如果你的内容被定义为 JSON，`parseHTML` 将完全被跳过，仅在粘贴时使用。\
而你的 `renderHTML` 方法确定内容在编辑器内的 HTML 表示方式。

`renderHTML` 可以在编辑器视图中通过节点视图和标记视图被覆盖，以允许对节点和标记的自定义渲染。

## 我想用 Tiptap 编辑 HTML 内容

Tiptap 是基于 Prosemirror 构建的，并不是一个任意的 HTML 编辑器，它是一个富文本编辑器，需要对正在编辑的 HTML 拥有完全的控制权来进行更改。Prosemirror 通过尝试以符合模式的方式解析内容来实现这一点（该模式源于你作为 Tiptap 扩展指定的节点和标记），这意味着不符合模式的内容将会丢失。这是一个权衡，Prosemirror 可以接受相当数量的 HTML 内容，并将其解析为结构化格式，但无法可靠地处理任意 HTML（在接受内容时比较宽松，但在输出时却很严格）。\
一个常见的情况是试图嵌套不同类型的标记，如：`<span class="my-class"><span style="color: red">可编辑文本</span></span>` 这两个标记无法这样嵌套，Prosemirror 将通过丢弃其中一个来试图修复这一点，以遵循标记无法相互包裹的规则。要解决此问题，输入到编辑器的 HTML 应该采用一个带有多个属性的元素的格式，如：`<span class="my-class" style="color: red">可编辑文本</span>`，Prosemirror 将正确解析这一格式，因为它试图将两个标记应用于文本。

在 Prosemirror 中没有配置此行为的方法，因为解析任意 HTML 已经相当复杂。根据你试图解析的 HTML 来源，你可以：

- 依赖默认行为并丢弃未知内容
- 尝试自己用自定义 HTML 解析器解析 HTML，并使其符合 Prosemirror 的期望（例如合并 `<span>`）

## React 上下文在 NodeViews 中无法工作

要在 NodeView 中使用 React 上下文，你需要用上下文提供者包装 EditorContent 组件。在 nodeview 中，上下文应该可以在 NodeView 组件中使用。

```jsx
import React from 'react'
import { EditorContent } from '@tiptap/react'

const TiptapEditor = ({ editor }) => {
  return (
    <MyContext.Provider value={{ foo: 'bar' }}>
      <EditorContent editor={editor} />
    </MyContext.Provider>
  )
}
```

## 为什么使用 React Node View 时会有额外的 div

这些 div 存在的原因是 prosemirror 期望同步生成一个节点视图，而 React 只能异步渲染。因此，我们注入一个元素，然后让 React 异步渲染到该元素中。这导致在 DOM 中有一个包装 div。

同样，当使用 `NodeViewContent` 时，有一个由 React 创建的元素，然后 Prosemirror 渲染到该元素中。这必须存在作为从 React 到 Prosemirror 的交接，因为 React 的默认行为是清除它正在渲染的元素，我们需要确保 React 不会销毁 prosemirror 正在尝试渲染富文本的元素。

因此，可以说，由于 React 的工作方式，没有好的方法去除这些中间元素。你只能使用 JS NodeView API 或 Vue，因为这两者的渲染方式更为合理。
