欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Angular中使用MathJax遇到的一些问题

程序员文章站 2022-11-29 20:14:11
前言 话说我本来是倾向于 katex 的,因为我感觉他很快,而且 mathjax 似乎很难配。但是大家表示对缺少功能的 katex 并无好感,给我提供了一些钻研 math...

前言

话说我本来是倾向于 katex 的,因为我感觉他很快,而且 mathjax 似乎很难配。但是大家表示对缺少功能的 katex 并无好感,给我提供了一些钻研 mathjax 的动力。

mathjax简介

mathjax是一款运行在浏览器中的开源数学符号渲染引擎,使用mathjax可以方便的在浏览器中显示数学公式,不需要使用图片。目前,mathjax可以解析latex、mathml和asciimathml的标记语言。mathjax项目于2009年开始,发起人有american mathematical society, design science等,还有众多的支持者,个人感觉mathjax会成为今后数学符号渲染引擎中的主流,也许现在已经是了。

个人其实也不算钻研,因为实际上 mathjax 很简单,调用 mathjax.hub.queue(['typeset', mathjax.hub, this.element.nativeelement]); 就可以渲染一个元素(这个 this.element.nativeelement 是从 angular 中调用它 dom 的语法),这个 .queue 实际上是 mathjax 自己实现的回调格式,语法非常清奇,参数个数不定,每个都是数组,代表一个回调,顺序执行。比如这个 ['typeset', mathjax.hub, this.element.nativeelement] ,第一个元素是方法名,第二个元素是 this ,之后的元素都是参数……

我们可以看到这个就相当于执行 mathjax.hub.typeset(this.element.nativeelement) ,那为啥不执行这个?因为这方法是同步的,会导致页面十分卡。于是 mathjax 就自己封装了一个异步队列(它的 api 可能几百年没改了)

我们说回 angular。因为要用 markdown,我的思路是用 marked 封装一个 directive。那么我们就应该在 marked 渲染完成之后用 mathjax 去 typeset 这个组件。但真的这样做了,却产生了奇妙的效果——切换页面之后,要等将近一分钟才开始渲染。我在它的队列里放了几个 log,发现每个元素都被 queue 了 4 次,几十个元素,难怪要一分钟才开始渲染下一页的内容,即使大部分 markdown 里面根本没有数学。

这时候我开始灰心了,这个问题就没有解决办法了吗?绝望之时,我想到能不能直接 typeset document,结果是可以的,而且十分快。所以渲染并不慢,可能是渲染的初始化过程比较慢。那么这时候方案就出来了,我们可以尽量减少渲染次数,同时只渲染 document。只要这个渲染还在进行,那么有再多的元素 queue 上来,我们也只当作 queue 了一次。

于是我就写了这么个 service:

@injectable()
export class mathjaxservice {
 public isqueued = false;
 public isrunning = false;
 window: any;
 constructor(@inject(platform_id) private platformid: object) {
 if (isplatformbrowser(this.platformid)) {
 this.window = window as any;
 }
 }
 finishrunning() {
 this.isrunning = false;
 if (this.isqueued) {
 this.queuechange();
 }
 }
 queuechange() {
 if (this.isrunning) {
 this.isqueued = true;
 } else {
 this.isqueued = false;
 this.isrunning = true;
 if (isplatformbrowser(this.platformid)) {
 if (this.window.mathjax) {
  this.window.mathjax.hub.config({
  messagestyle: 'none',
  tex2jax: {
  // preview: 'none',
  inlinemath: [['$', '$']],
  processescapes: true
  }
  });
  this.window.mathjax.hub.queue(['log', console, 'start'], ['typeset', this.window.mathjax.hub, document], ['log', console, 'end'], ['finishrunning', this]);
 }
 } else {
 this.finishrunning();
 }
 }
 }
}

事实证明,它能圆满完成任务,它也就是现在运行在 上的代码。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。