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 相关文章推荐
flash javascript之间的通讯方法小结
Dec 20 Javascript
js限制input标签中只能输入中文
Jun 26 Javascript
PHP结合jQuery实现的评论顶、踩功能
Jul 22 Javascript
js点击按钮实现带遮罩层的弹出视频效果
Dec 19 Javascript
JavaScript中数组的各种操作的总结(必看篇)
Feb 13 Javascript
AngularJS折叠菜单实现方法示例
May 18 Javascript
通过命令行创建vue项目的方法
Jul 20 Javascript
详解win7 cmd执行vue不是内部命令的解决方法
Jul 27 Javascript
详解react native页面间传递数据的几种方式
Nov 07 Javascript
vue使用map代替Aarry数组循环遍历的方法
Apr 30 Javascript
javascript局部自定义鼠标右键菜单
Dec 08 Javascript
cypress测试本地web应用
Jun 01 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
MYSQL 小技巧 -- LAST_INSERT_ID
2009/11/24 PHP
PHP遍历目录并返回统计目录大小
2014/06/09 PHP
PHP实现从远程下载文件的方法
2015/03/12 PHP
PHP实现支持加盐的图片加密解密
2016/09/09 PHP
Discuz论坛密码与密保加密规则
2016/12/19 PHP
Prototype使用指南之base.js
2007/01/10 Javascript
AngularJS基础学习笔记之指令
2015/05/10 Javascript
zepto中使用swipe.js制作轮播图附swipeUp,swipeDown不起效果问题
2015/08/27 Javascript
详解堆的javascript实现方法
2016/11/29 Javascript
js实现前端图片上传即时预览功能
2017/08/02 Javascript
js实现购物车功能
2018/06/12 Javascript
微信小程序利用swiper+css实现购物车商品删除功能
2019/03/06 Javascript
vue-cli3 取消eslint校验代码的解决办法
2020/01/16 Javascript
原生JS实现记忆翻牌游戏
2020/07/31 Javascript
vue+element使用动态加载路由方式实现三级菜单页面显示的操作
2020/08/04 Javascript
js节流防抖应用场景,以及在vue中节流防抖的具体实现操作
2020/09/21 Javascript
Vue select 绑定动态变量的实例讲解
2020/10/22 Javascript
Python中设置变量访问权限的方法
2015/04/27 Python
python中使用psutil查看内存占用的情况
2018/06/11 Python
Pytorch技巧:DataLoader的collate_fn参数使用详解
2020/01/08 Python
Pycharm pyuic5实现将ui文件转为py文件,让UI界面成功显示
2020/04/08 Python
2020最新pycharm汉化安装(python工程狮亲测有效)
2020/04/26 Python
Django URL参数Template反向解析
2020/11/24 Python
日本高端护肤品牌:Tatcha
2016/08/29 全球购物
中东地区最大的奢侈品市场:The Luxury Closet
2019/04/09 全球购物
请用Java实现列出某个目录下的所有文件
2013/09/23 面试题
经济管理专业毕业生自荐信范文
2014/01/02 职场文书
迎接领导欢迎词
2014/01/11 职场文书
施工安全承诺书
2014/05/22 职场文书
学校禁毒宣传活动总结
2015/05/08 职场文书
交通事故责任认定书
2015/08/06 职场文书
导游词之青岛太清宫
2019/12/13 职场文书
CSS3 制作的彩虹按钮样式
2021/04/11 HTML / CSS
详解MindSpore自定义模型损失函数
2021/06/30 Python
使用canvas对video视频某一刻截图功能
2021/09/25 HTML / CSS
教你快速构建一个基于nginx的web集群项目
2021/11/27 Servers