野声

Hey, 野声!

谁有天大力气可以拎着自己飞呀
twitter
github

ReactプロジェクトでMathjaxを動的にロードする

React プロジェクトを作成する際、数学の式をウェブページ上にレンダリングしたいが、他の React コンポーネントを使用したくない場合、動的なロードを使用して DOM を直接レンダリングします。

Mathjax@3 は大幅に更新され、使用方法も 2.x バージョンと異なります。

React での動的な js のロード#

まず、動的に js をロードする方法を知る必要があります。js を新しいスクリプトノードにマウントして、DOM に追加するだけです。

script要素を作成し、src属性にロードするリンクを設定し、ノードを body 要素に追加します。

以下のように関数をラップするだけで、ロードする js のリンクを渡すだけで、.thenメソッドを使用して後続の操作を行うことができます。

export const loadJS = (url: string) =>
  new Promise(function (resolve, reject) {
    const script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = url;
    document.body.appendChild(script);
    script.onload = function () {
      resolve(`success: ${url}`);
    };
    script.onerror = function () {
      reject(Error(`${url} load error!`));
    };
  });

使用する場所:

loadJS(url)
  .then(() => {
    // 何かを実行
  })
  .catch(() => {
    // 何かを実行
  });

[email protected]バージョン#

まず、参考になる公式リンクを示します。この記事ではわかりにくいかもしれません。

Mathjax をロードした後、適切なタイミングで mathjax が DOM をレンダリングするだけです。

例を挙げます:

componentDidMount() {
  const mathjaxUrl = 'https://cdn.bootcss.com/mathjax/2.7.4/MathJax.js?config=TeX-AMS_CHTML';
  loadJS(mathjaxUrl).then(() => {
    this.showMathjax();
  });
}

componentDidUpdate () {
  if (!(window as any).MathJax) {
    (window as any).MathJax.Hub.Queue(['Typeset', (window as any).MathJax.Hub, ReactDOM.findDOMNode(this)]);
  }
}

showMathjax = () => {
  if ((window as any).MathJax) {
    (window as any).MathJax.Hub.Config({
      tex2jax: {
        inlineMath: [['$', '$']],
        displayMath: [['$$', '$$']],
        skipTags: ['script', 'noscript', 'style', 'textarea', 'code', 'a'],
      },
      CommonHTML: {
        scale: 120,
        linebreaks: { automatic: true },
      },
      'HTML-CSS': { linebreaks: { automatic: true } },
      SVG: { linebreaks: { automatic: true } },
      TeX: { noErrors: { disabled: true } },
    });
  } else {
    setTimeout(this.showMathjax, 1000);
  }
};

2.x のバージョンでは、Mathjax.Hub.Configを使用して設定する必要があります。これらの設定は理解しやすく、tex2jaxでは数学の式をどのようにレンダリングするかを設定しています。

インラインの数式は$...$で囲み、複数行の数式は$$...$$で囲みます。どのタグ内のものはレンダリングしないように設定しています。
次に、いくつかのモードでのレンダリングの表示方法を設定します。上記でロードした js の後ろに?config=TeX-AMS_CHTMLがあることから、ロードしたのは CHTML の設定であり、さまざまな設定によって表示が異なります。参照:https://docs.mathjax.org/en/v2.7-latest/config-files.html

Mathjaxがロードされると、ページがレンダリングされますが、シングルページアプリケーションでは、Mathjaxはページの DOM が更新されるたびに再レンダリングされません。MathJax.Hub.Queue(['Typeset', MathJax.Hub, ReactDOM.findDOMNode(this)]);を使用して、Mathjaxに DOM を手動でレンダリングさせる必要があります。componentDidUpdateに追加してください。

mathjax@3 バージョン#

同様に公式ドキュメントのリンクを提供します:

3 のバージョンでは、Mathjaxのロードと設定方法が異なります。

v2 から v3 へのアップグレード:http://docs.mathjax.org/en/latest/upgrading/v2.html

ロード時には、異なる設定の js を直接ロードすることができます。?config=xxxは不要です。たとえば、https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.jsをロードします。

Mathjax.Hubメソッドは削除され、設定は単にwindow.Mathjaxに設定オブジェクトを割り当てるだけです。

公式では、設定を変換するためのツールも提供しています: MathJax Configuration Converter

設定の例を示します:

(window as any).MathJax = {
  tex: {
    inlineMath: [['$', '$']],
    displayMath: [['$$', '$$']],
  },
  options: {
    skipHtmlTags: ['script', 'noscript', 'style', 'textarea', 'code', 'a'],
  },
  chtml: {
    scale: 1.2,
  },
  startup: {
    ready: () => {
      (window as any).MathJax.startup.defaultReady();
      (window as any).MathJax.startup.promise.then(() => {
        console.log('MathJax initial typesetting complete');
      });
    },
  },
};

Mathjaxスクリプトがロードされると、window.Mathjaxを設定として読み取り、Mathjaxオブジェクトに置き換えます。その後、関連する関数を呼び出すことができます。

Mathjaxが初期化されると、設定のstartup.readyメソッドが呼び出されます。ここで、ヒントやその他の設定を行うことができます。

問題は同じですが、DOM が更新されるとMathjaxは再レンダリングされません。MathJax.typesetPromise()メソッドを使用する必要があります。componentDidUpdateで設定してください。

componentDidUpdate() {
  const MathJax = (window as any).MathJax;
  if (MathJax) {
    MathJax.typesetPromise && MathJax.typesetPromise();
  }
}

このメソッドは非同期メソッドであり、同じ機能を持つ同期メソッドMathJax.typeset()もあります。

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。