收到数据后渲染 MathJax

Rendering MathJax after data is received

我正在从 http 请求接收数据(包含 LaTeX 代码),我想用 MathJax 呈现它。但是,MathJax 似乎在实际接收到数据之前就开始渲染代码。为了重现该错误,我使用 setTimeout500 毫秒来模拟 HTTP 请求。这是一个显示我正在尝试做的事情的例子:

HTML

<html>
<head>
<title>MathJax Test</title>
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
<script>
     MathJax = {
            tex: {
                inlineMath: [['$', '$'], ['\(', '\)']]
            }
        }
</script>
<script type="text/javascript" id="MathJax-script" async
  src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js">
</script>
</head>
<body>
<div id="div1">
<!--  JS fills this div-->

</div>

</body>
</html>

JS

window.addEventListener('DOMContentLoaded', (event) => {

  var para = document.createElement("p");
  var element = document.getElementById("div1");
  
  // Load the element after a delay of 500 ms
  setTimeout(() => {
    para.innerText = '$x=x^2+1$'
    element.appendChild(para)
  }, 500)
})

这是一个包含上述代码的 JSFiddle:https://jsfiddle.net/0uo5fhw9/100/

如您在 JSFiddle 中所见,LaTeX 未呈现。我该如何解决这个问题并告诉 MathJax 在所有数据加载完成后进行渲染?

好吧,如果您从 html 中删除第三个脚本,然后像这样在延迟函数中添加它:

    setTimeout(() => {
        var script = document.createElement('script');
        script.src = "https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js";
        script.type = "text/javascript";
        script.id = "MathJaz-script";
        script.async = true;
        document.getElementsByTagName('head')[0].appendChild(script);
    }, 5000)

有效。这将显示实际文本,然后在延迟后将其转换为 MathJax。如果不希望文本在渲染前显示,可以在追加脚本后的timeout函数中设置。

你的HTML:

<html>
<head>
<title>MathJax Test</title>
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
<script>
     MathJax = {
            tex: {
                inlineMath: [['$', '$'], ['\(', '\)']]
            }
        }
</script>
</head>
<body>
<div id="div1">

</div>

</body>
</html>

你的 JS:

window.addEventListener('DOMContentLoaded', (event) => {

  var para = document.createElement("p");

  var element = document.getElementById("div1");
    para.innerText = '$x=x^2+1$'
    element.appendChild(para)
  
  setTimeout(() => {
  var script = document.createElement('script');
    script.src = "https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js";
  script.type = "text/javascript";
  script.id = "MathJaz-script";
  script.async = true;
    document.getElementsByTagName('head')[0].appendChild(script);
  }, 5000)
})

MathJax 在 DOMContentLoaded 事件发生时对页面内容进行排版,因此如果在此之后更改页面,如您的示例所示,则需要让 MathJax 再次排版页面。有关详细信息,请参阅 documentation,但您可以使用 MathJax.typeset()MathJax.typesetPromise() 方法。

这是您的示例,已修改为:

window.addEventListener('DOMContentLoaded', (event) => {

  var para = document.createElement("p");
  var element = document.getElementById("div1");
  
  // Load the element after a delay of 500 ms
  setTimeout(() => {
    para.innerText = '$x=x^2+1$';
    element.appendChild(para);
    if (MathJax) MathJax.typesetPromise();
  }, 500);
})
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
<script>
     MathJax = {
            tex: {
                inlineMath: [['$', '$'], ['\(', '\)']]
            }
        }
</script>
<script type="text/javascript" id="MathJax-script" async
  src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js">
</script>
</head>
<body>
<div id="div1">
<!--  JS fills this div-->

</div>