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 相关文章推荐
用jscript实现新建和保存一个word文档
Jun 15 Javascript
js 数组的for循环到底应该怎么写?
May 31 Javascript
functional继承模式 摘自javascript:the good parts
Jun 20 Javascript
javascript通过className来获取元素的简单示例代码
Jan 10 Javascript
JavaScript字符串对象的concat方法实例(用于连接两个或多个字符串)
Oct 16 Javascript
IE8中动态创建script标签onload无效的解决方法
Dec 22 Javascript
阿里巴巴技术文章分享 Javascript继承机制的实现
Jan 14 Javascript
Vue.js 2.0 移动端拍照压缩图片上传预览功能
Mar 06 Javascript
基于vue写一个全局Message组件的实现
Aug 15 Javascript
关于JSON解析的实现过程解析
Oct 08 Javascript
selenium+java中用js来完成日期的修改
Oct 31 Javascript
JS删除数组指定值常用方法详解
Jun 04 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
php去除字符串换行符示例分享
2014/02/13 PHP
Laravel 5 框架入门(四)完结篇
2015/04/09 PHP
php动态函数调用方法
2015/05/21 PHP
php封装好的人民币数值转中文大写类
2015/12/20 PHP
PHP中strncmp()函数比较两个字符串前2个字符是否相等的方法
2016/01/07 PHP
PHP 7安装使用体验之性能大提升,兼容性强,扩展支持不够(升级PHP要谨慎)
2017/07/27 PHP
javascript操纵OGNL标签示例代码
2014/06/16 Javascript
jQuery制作简洁的图片轮播效果
2015/04/03 Javascript
JS组件Bootstrap Table布局详解
2016/05/27 Javascript
JQuery统计input和textarea文字输入数量(代码分享)
2016/12/29 Javascript
js实现4个方向滚动的球
2017/03/06 Javascript
vue.js 左侧二级菜单显示与隐藏切换的实例代码
2017/05/23 Javascript
angular中使用Socket.io实例代码
2017/06/03 Javascript
javascript input输入框模糊提示功能的实现
2017/09/25 Javascript
jQuery实现通过方向键控制div块上下左右移动的方法【测试可用】
2018/04/26 jQuery
vue-cli3.0 环境变量与模式配置方法
2018/11/08 Javascript
微信小程序登录态和检验注册过没的app.js写法
2019/05/22 Javascript
JS+HTML5本地存储Localstorage实现注册登录及验证功能示例
2020/02/10 Javascript
vue-cli+webpack项目打包到服务器后,ttf字体找不到的解决操作
2020/08/28 Javascript
vue element-ul实现展开和收起功能的实例代码
2020/11/25 Vue.js
python实现flappy bird小游戏
2018/12/24 Python
python使用pymongo操作mongo的完整步骤
2019/04/13 Python
python障碍式期权定价公式
2019/07/19 Python
如何使用Python发送HTML格式的邮件
2020/02/11 Python
为什么是 Python -m
2020/06/19 Python
Python函数调用追踪实现代码
2020/11/27 Python
纯CSS打造(无图像无js)的非常流行的讲话(语音)气泡效果
2012/12/28 HTML / CSS
html5.2 dialog简介详解
2018/02/27 HTML / CSS
德国价格合理的品牌商品购物网站:averdo
2019/03/21 全球购物
俄罗斯花园种植材料批发和零售网上商店:Беккер
2019/07/22 全球购物
大学生迟到检讨书500字
2014/10/17 职场文书
党员评议个人总结
2014/10/20 职场文书
重阳节慰问信
2015/02/15 职场文书
2019旅游导游工作总结
2019/06/27 职场文书
python自动化调用百度api解决验证码
2021/04/13 Python
vue+elementUI实现表格列的显示与隐藏
2022/04/13 Vue.js