Angular中使用MathJax遇到的一些问题
前言
话说我本来是倾向于KaTeX的,因为我感觉他很快,而且MathJax似乎很难配。但是大家表示对缺少功能的KaTeX并无好感,给我提供了一些钻研MathJax的动力。
MathJax简介
MathJax是一款运行在浏览器中的开源数学符号渲染引擎,使用MathJax可以方便的在浏览器中显示数学公式,不需要使用图片。目前,MathJax可以解析Latex、MathML和ASCIIMathML的标记语言。MathJax项目于2009年开始,发起人有AmericanMathematicalSociety,DesignScience等,还有众多的支持者,个人感觉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里面根本没有数学。
这时候我开始灰心了,这个问题就没有解决办法了吗?绝望之时,我想到能不能直接Typesetdocument,结果是可以的,而且十分快。所以渲染并不慢,可能是渲染的初始化过程比较慢。那么这时候方案就出来了,我们可以尽量减少渲染次数,同时只渲染document。只要这个渲染还在进行,那么有再多的元素queue上来,我们也只当作queue了一次。
于是我就写了这么个service:
@Injectable() exportclassMathjaxService{ publicisQueued=false; publicisRunning=false; window:any; constructor(@Inject(PLATFORM_ID)privateplatformId:Object){ if(isPlatformBrowser(this.platformId)){ this.window=windowasany; } } 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(); } } } }
事实证明,它能圆满完成任务,它也就是现在运行在这个网站上的代码。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。