You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中Tiptap编辑器插入MathJax非HTML节点的问题求助

解决Tiptap插入MathJax节点被移除的问题

Tiptap基于ProseMirror,默认只允许标准HTML节点,像mjx-container、math这类非标准节点会被自动过滤。要解决这个问题,你需要扩展Tiptap的Schema,让编辑器支持这些自定义节点,具体步骤如下:

1. 创建支持MathJax节点的Tiptap扩展

新建一个自定义扩展,让编辑器能识别并保留MathJax生成的节点:

import { Node } from '@tiptap/core';

export const MathJaxNode = Node.create({
  name: 'mathjax',
  group: 'block inline',
  inline: true, // 设为true可让公式嵌入段落内
  selectable: true,
  draggable: true,

  // 定义节点允许容纳的内容
  content: 'inline*',

  // 解析DOM时识别MathJax相关节点
  parseDOM: [
    {
      tag: 'mjx-container',
      contentElement: 'mjx-container',
    },
    {
      tag: 'math',
      contentElement: 'math',
    },
  ],

  // 渲染DOM时输出对应节点
  toDOM: () => ['mjx-container', { class: 'MathJax' }, 0],
});

2. 在Tiptap编辑器中注册该扩展

初始化编辑器时,将自定义的MathJaxNode加入扩展列表:

import { Editor } from '@tiptap/react';
import { MathJaxNode } from './MathJaxNode';

const editor = new Editor({
  extensions: [
    // 保留你的其他默认扩展(如Paragraph、Text等)
    MathJaxNode,
  ],
  content: '',
});

3. 正确插入MathJax渲染后的内容

不要直接插入React元素,先获取MathJax生成的HTML字符串,再用Tiptap的insertHTML命令插入:

// 假设已通过better-react-mathjax渲染得到公式HTML
const mathjaxHtml = '<mjx-container class="MathJax"><math xmlns="http://www.w3.org/1998/Math/MathML"><mi>x</mi><mo>=</mo><mfrac><mrow><mo>−</mo><mi>b</mi><mo>±</mo><msqrt><msup><mi>b</mi><mn>2</mn></msup><mo>−</mo><mn>4</mn><mi>a</mi><mi>c</mi></msqrt></mrow><mrow><mn>2</mn><mi>a</mi></mrow></mfrac></math></mjx-container>';

// 插入到编辑器
editor.commands.insertHTML(mathjaxHtml);

额外优化:禁止直接编辑公式节点

如果不想让用户直接修改公式的DOM结构,可以在扩展里设置editable: false,同时提供弹窗让用户编辑LaTeX代码后重新渲染:

export const MathJaxNode = Node.create({
  // ...其他配置
  editable: false,

  addNodeView() {
    return ({ node, editor }) => {
      const dom = document.createElement('mjx-container');
      dom.innerHTML = node.textContent;
      
      // 点击节点打开LaTeX编辑弹窗
      dom.addEventListener('click', () => {
        const latex = prompt('编辑LaTeX公式:', node.attrs.latex);
        if (latex) {
          // 重新渲染公式并替换节点
          const newHtml = renderMathJax(latex); // 你的MathJax渲染函数
          editor.commands.replaceHTML(newHtml);
        }
      });

      return { dom };
    };
  },
});

配置完成后,Tiptap就不会再移除mjx-container这类节点,公式即可正常显示。

内容的提问来源于stack exchange,提问作者Karthik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 07:33:25