使用 MathJax 和 JQuery 插入 MathML

Inserting MathML using MathJax and JQuery

我最近开始在我的应用程序中使用 MathJax,使用 JQuery 来尝试为 Intuitionistic/Constructive 逻辑创建一个编辑器。我面临的问题是,每当页面加载并且我使用 JQuery 注入 MathML 时,它都无法正确呈现。这是代码

<math display="block" id="mathml-derivation">
    <mrow class="beginning">
    </mrow>
</math>

这是javascript

setTimeout(function() {
            console.log("Started");
            var $frac = document.createElement('mfrac');
            $frac.innerHTML = '<mrow id="children' + parseInt(1) + '" class="conclusion">\
                            <mrow>\
                                <mi>b</mi>\
                            </mrow>\
                        </mrow>\
                        <mrow class="assumption">\
                            <mo>' + "\u22A2" + '</mo>\
                            <mrow class="goal clickable">\
                                <mi>a</mi>\
                            </mrow>\
                        </mrow>';
            $("#mathml-derivation").append($frac);
            console.log($frac);
            MathJax.Hub.Typeset("mathml-derivation");
        }, 1000);

我不确定是什么问题。我有一个 setTimeout 函数的原因是为了确保它在页面加载后至少执行一秒钟。当我立即或通过事件加载它时,MathML 无法正确呈现。我关注了 Whosebug 上的其他一些帖子,它说要使用“.Typeset”功能,但它无法正常工作。

最后一点,我正在使用 Chrome 进行开发,并且我正在使用 MathJax 来实现兼容性。

您的 jsfiddle 示例存在几个问题。

您使用超时看到的不稳定行为是由于您的 MathJax 和 jQuery 代码之间缺乏同步。在您的 jQuery 代码 运行 之前,MathJax 可能已完全加载,也可能未完全加载。所以你最终会遇到一场比赛:当你设置一个低超时时,jQuery 部分首先 运行s 并替换页面中的(尚未经过 MathJax 处理的)MathML;然后 MathJax 进来并呈现它在 DOM 中找到的内容。

随着超时时间的延长,您将看到当 MathJax 运行 首先出现时会发生什么 - 而您 运行 进入第二个问题:MathJax 从 DOM 但在其输出中保留来自源的 ids。这意味着 jQuery 部分最终将 MathML 片段附加到 MathJax 的(HTML 或 SVG)输出(从而破坏它)。

现在 MathJax.Hub.Typeset("mathml-derivation");(这并不理想,因为您应该始终使用 MathJax 的队列)将仅呈现新的数学内容。但是,您的代码只是在输出中进行修改,而没有让 MathJax 知道发生了一些变化。所以排队一个普通的排版不会对该特定节点做任何事情。如果您要求 MathJAx 使用 MathJax.Hub.Queue(["Rerender", MathJax.Hub]); 重新呈现,您仍然看不到任何效果,因为第二个问题是将 MathML 添加到输出而不是 MathJax 内部使用的源。

长话短说,您需要重新设计 MathJax 和 jQuery 之间的交互。您可能想使用 MathJax 的排队机制,因为它是高度异步的。 MathJax documentation 还描述了一些解决页面上数学更新问题的方法; "MathJax way" 将通过 text 方法更新源代码,尽管大多数开发人员会懒惰地删除整个输出节点并插入更改后的 MathML 并只是排队 typeset(因为现在有新的DOM 中的数学)。

请注意,MathJax 不提供用于修改子表达式的 API,因此您必须自己进行跟踪,例如,保留一个表示 MathML 表达式状态的内部 DOM 节点,修改它,然后将其复制到 DOM 以更新视觉输出。