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

 更新时间:2017年12月15日 09:34:51   作者:神奇魔法咸鱼堂  
这篇文章主要给大家介绍了关于Angular中使用MathJax遇到的一些问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友下面来一起学习学习吧。

前言

话说我本来是倾向于 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();
 }
 }
 }
}

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

总结

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

相关文章

  • AngularJS 表达式详解及实例代码

    AngularJS 表达式详解及实例代码

    这篇文章主要介绍了AngularJS 表达式,这里整理了详细的资料,有需要的小伙伴可以参考下
    2016-09-09
  • angularJS提交表单(form)

    angularJS提交表单(form)

    这篇文章主要介绍了angularJS提交表单(form)的方法和示例,需要的朋友可以参考下
    2015-02-02
  • Angular 1.x个人使用的经验小结

    Angular 1.x个人使用的经验小结

    这篇文章主要给大家介绍了关于Angular 1.x个人使用的一些经验,属于一些基础入门教程,文中通过示例代码介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面来一起看看吧。
    2017-07-07
  • 详解angular用$sce服务来过滤HTML标签

    详解angular用$sce服务来过滤HTML标签

    这篇文章主要介绍了详解angular用$sce服务来过滤HTML标签,具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2017-04-04
  • 详解Angular项目中共享模块的实现

    详解Angular项目中共享模块的实现

    本文主要介绍了Angular的共享模块的实现,对此感兴趣的同学,可以实验一下
    2021-05-05
  • Angular.js自定义指令学习笔记实例

    Angular.js自定义指令学习笔记实例

    这篇文章主要介绍了Angular.js自定义指令的实例代码,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2017-02-02
  • 简介AngularJS中使用factory和service的方法

    简介AngularJS中使用factory和service的方法

    这篇文章主要简单介绍了AngularJS中使用factory和service的方法,主要针对自定义工厂和服务的创建来讲,需要的朋友可以参考下
    2015-06-06
  • AngularJS的内置过滤器详解

    AngularJS的内置过滤器详解

    在我们开发中经常需要在页面显示给用户的信息需要一定处理格式化,才能显示给用户。在angularjs中为我们提供了叫filter的指令,让我们能够很轻易就能做到着一些列的功能,angularjs内部为我们提供了number等很多内置的filter。
    2015-05-05
  • Angular的$http与$location

    Angular的$http与$location

    这篇文章主要为大家详细介绍了Angular的$http与$location,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-12-12
  • AngulaJS路由 ui-router 传参实例

    AngulaJS路由 ui-router 传参实例

    本篇文章主要介绍了AngulaJS路由 ui-router 传参实例 ,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-04-04

最新评论