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


Posted in Javascript onDecember 15, 2017

前言

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

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

总结

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

Javascript 相关文章推荐
使用JQuery和s3captche实现一个水果名字的验证
Aug 14 Javascript
jQuery Ajax提交表单查询获得数据实例代码
Sep 19 Javascript
一个简单的JS鼠标悬停特效具体方法
Jun 17 Javascript
JQuery显示隐藏DIV的方法及代码实例
Apr 16 Javascript
浅谈jquery中delegate()与live()
Jun 22 Javascript
基于jQuery实现的QQ表情插件
Aug 25 Javascript
使用Ajax生成的Excel文件并下载的实例
Nov 21 Javascript
快速入门Vue
Dec 19 Javascript
react 兄弟组件如何调用对方的方法示例
Oct 23 Javascript
如何使用electron-builder及electron-updater给项目配置自动更新
Dec 24 Javascript
详解babel升级到7.X采坑总结
May 12 Javascript
Javascript var变量删除原理及实现
Aug 26 Javascript
vue实现验证码输入框组件
Dec 14 #Javascript
基于滚动条位置判断的简单实例
Dec 14 #Javascript
微信小程序实现动态设置placeholder提示文字及按钮选中/取消状态的方法
Dec 14 #Javascript
ES6/JavaScript使用技巧分享
Dec 14 #Javascript
Django与Vue语法的冲突问题完美解决方法
Dec 14 #Javascript
浅析JS抽象工厂模式
Dec 14 #Javascript
JavaScript重复元素处理方法分析【统计个数、计算、去重复等】
Dec 14 #Javascript
You might like
在smarty模板中使用PHP函数的方法
2011/04/23 PHP
php计算指定目录下文件占用空间的方法
2015/03/13 PHP
JSON 教程 json入门学习笔记
2020/09/22 Javascript
可在线编辑网页文字效果代码(单击)
2013/03/02 Javascript
js 编码转换 gb2312 和 utf8 互转的2种方法
2013/08/07 Javascript
jquery内置验证(validate)使用方法示例(表单验证)
2013/12/04 Javascript
jquery判断元素是否隐藏的多种方法
2014/05/06 Javascript
javascript实现的简单计时器
2015/07/19 Javascript
JS实现放大、缩小及拖拽图片的方法【可兼容IE、火狐】
2016/08/23 Javascript
Angularjs通过指令监听ng-repeat渲染完成后执行脚本的方法
2016/12/31 Javascript
JavaScript使用math.js进行精确计算操作示例
2018/06/19 Javascript
页面内锚点定位及跳转方法总结(推荐)
2019/04/24 Javascript
ES6中异步对象Promise用法详解
2019/07/31 Javascript
vue改变循环遍历后的数据实例
2019/11/07 Javascript
javascript设计模式 ? 原型模式原理与应用实例分析
2020/04/10 Javascript
vue实现购物车案例
2020/05/30 Javascript
jQuery中event.target和this的区别详解
2020/08/13 jQuery
Python实现将Excel转换为json的方法示例
2017/08/05 Python
解决python读取几千万行的大表内存问题
2018/06/26 Python
Python for循环中的陷阱详解
2018/07/13 Python
钉钉群自定义机器人消息Python封装的实例
2019/02/20 Python
使用Python实现跳帧截取视频帧
2019/05/31 Python
python如何编写win程序
2020/06/08 Python
MVMT手表官方网站:时尚又实惠的高品质手表
2016/12/04 全球购物
美国学校用品、教室和教学商店:Discount School Supply
2018/04/04 全球购物
Java程序员面试90题
2013/10/19 面试题
会计专业毕业生自荐信范文
2013/12/20 职场文书
工地资料员岗位职责
2013/12/31 职场文书
关于赌博的检讨书
2014/01/24 职场文书
关于圣诞节的广播稿
2014/01/26 职场文书
大专生自我评价
2014/01/28 职场文书
学习型党组织心得体会
2014/09/12 职场文书
面试通知短信
2015/04/20 职场文书
2016年学校十一国庆节活动总结
2016/04/01 职场文书
如果用一句诗总结你的上半年,你会用哪句呢?
2019/07/16 职场文书
Mybatis 一级缓存和二级缓存原理区别
2022/09/23 Java/Android