Отрисовка MathJax после получения данных - PullRequest
0 голосов
/ 21 июня 2020

Я получаю данные (содержащие код LaTeX) из HTTP-запроса и хочу визуализировать их с помощью MathJax. Однако похоже, что MathJax начинает рендеринг кода до того, как данные фактически получены. Чтобы воспроизвести ошибку, я смоделировал HTTP-запрос, используя setTimeout из 500 мс. Вот пример, показывающий, что я пытаюсь сделать:

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 о рендеринге после загрузки всех данных?

Ответы [ 2 ]

0 голосов
/ 22 июня 2020

MathJax набирает содержимое страницы при возникновении события DOMContentLoaded, поэтому, если вы измените страницу после этого, как в вашем примере, вам нужно попросить MathJax снова набрать страницу. См. Подробности в документации , но вы можете сделать это с помощью методов 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>
0 голосов
/ 21 июня 2020

Хорошо, если вы удалите третий сценарий из 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. Если вы не хотите, чтобы текст отображался перед отрисовкой, вы можете установить его в функции тайм-аута после добавления скрипта.

Ваш 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)
})
...